1 Introduction

The subject of mathematics causes fear and difficulty for a wide range of students. We often hear students claim, “I don’t like math”, “I’m just not good at math”, “I’m not a math person”, or “I wasn’t born with the math gene”, etc. Although these claims are not perfect indicators of math anxiety, students who have these fixed mindsets will be more likely to experience math anxiety.

While math anxiety can have a serious impact on academic performance, it does not mean a lack of mathematics ability. Prof. Laurent Schwartz experienced math anxiety in the 11th grade, but this did not prevent him from becoming a prominent mathematician. In fact, he won the Fields Model (the mathematician’s Nobel Prize) in 1950. Effectively managing math anxiety requires a deep understanding of math anxiety.

This project aims to identify factors that are strongly associated with math anxiety and use them to reduce math anxiety and, consequently, improve academic performance. Specifically:

  1. The results of this project will contribute to the body of existing knowledge.

  2. Identification of environmental factors aids the development of intervention tools for educators and support staff to help students reduce math anxiety and improve their academic performance.

  3. The outcomes of this project can be used to implicitly improve retention.

2 Literature Review

Mathematics anxiety involves feelings of fear, tension, apprehension, and physiological reactivity interfering when individuals engage with number manipulation and mathematical problem-solving (see, for example, Pletzer et al. 2016). In the U.S., an estimated 25% of four-year college students and up to 80% of community college students suffer from a moderate to a high degree of mathematics anxiety (Chang & Beilock, 2016). The frequency of negative effects of math anxiety on college students is increasing.

The earliest research on math anxiety can be traced back to Gough (1954) who used the term mathemaphobia. The term math anxiety was first used by Dreger and Aiken (1957). The first definition of math anxiety is credited to Richardson and Suinn (1972), who described math anxiety as “feelings of tension and anxiety that interfere with the manipulation of numbers and solving of mathematical problems in a wide variety of ordinary life and academic situations”.

In the past 70 years, numerous authors conducted extensive research on math anxiety. Particularly, in the past 20 years, researchers from different disciplines including mathematics have investigated the association between math anxiety and math achievement, the causes of math anxiety, characteristics of students that increase susceptibility to math anxiety, and efforts that educators can take to remedy it.

Math anxiety is real. Its negative impact on students’ academic performance and their future professional life is profound. Extensive research publications since 2000 have shown that math anxiety relates inversely to positive attitudes toward mathematics and is bound directly to avoidance of the subject (see for example, Segool et al., 2013). It affects both math and overall academic performance since math anxiety leads to the drainage of cognitive resources, motivation reduction, and strategy impairment (Klee et al., 2022).

Math anxiety can also lead to poor academic performance and course withdrawal, putting students behind schedule and increasing the risk of drop out, which reduces student retention rates. Wilson (2013) studied math anxiety of mature-age pre-service teachers as a potential contributing factor that impacts student retention. Daker et al. (2021) recently studied the impact of math anxiety on first-year STEM students and concluded that math anxiety predicts STEM avoidance and underperformance throughout the university, independently of math ability.

A wealth of empirical studies on various aspects of math anxiety have been conducted since Dreger & Aiken’s (1957) seminal work. Due to the complex pathways toward the development of math anxiety and its links with achievements and confounders, the origins and outcomes of math anxiety are still not fully understood.

Recent and ongoing research focuses on the development and dynamic interplay between factors that cause math anxiety. Most of the research can be classified into three categories: situational, dispositional, and environmental (O’Leary et al., 2017). The current project will explore all three types of factors, but the primary focus is on the environmental factors such as prior perceptions, attitudes, and experiences that have affected the individual.

3 Research Objectives

Since lower mathematics achievement predicts higher subsequent math anxiety and higher math anxiety predicts lower future achievement, reducing math anxiety will help students develop a positive attitude to mathematics, build confidence, boost motivation, and consequently improve their achievements. This study aimed to identify the factors that can reduce math anxiety in college students. Specific objectives are

Objective 1: Adopting well-established psychometric survey instruments AMAS and self-efficacy instruments to collect math anxiety and self-efficacy data.

Objective 2: Include some demographic characteristics such as age and gender to compare the results with that of existing research and use them as a baseline.

Objective 3: Teaching strategies can reduce math anxiety and improve learning outcomes. We will investigate several different strategies in mathematics teaching such as conceptual, procedure, etc., to see if these strategies affect the level of math anxiety.

Objective 4: Effectively using the technologies can reduce math anxiety. The recently developed educational technologies during the pandemic have not been discussed in the literature on math anxiety. We will investigate how these new technologies affect math anxiety.

Objective 5: Learning modalities and styles are also associated with math anxiety. Most of the research in this direction is based on high school students. We will explore how these learning modalities and styles affect math anxiety among college students.

Objective 6: Creating and using campus learning resources can reduce math anxiety and improve their academic performance (Moliner & Alegre, 2020). We will explore whether and how learning resources on college campuses reduce anxiety.

4 Materials

4.1 Participants

The survey was approved by WCU’s IRB. We invite all WCU students who take their first WCU mathematics and statistics class in the fall semesters of 2024 and the spring semester of 2025. Participation in the study are voluntary and responses remain anonymous. The data was collected in the spring and fall semesters of 2024 based on the protocols set by WCU’s Institutional Research. Via Qualtrics, we sent an invitation email to all qualified students spring and fall mid-semester. A reminder email was sent at the end of the semester to non-responding students to boost the participation rate. A $10 Amazon gift card was offered to survey completers and distributed through Qualtrics so anonymity is guaranteed.

The study population in this study is defined as WCU students aged 18 years or older who took their first MAT class at WCU. The results in this study can be generalized to similar regional universities and those recently reclassified R2 institutions.

4.2 Survey Instruments

The survey will have three components:

  1. Multi-item Survey Instrument Math Anxiety: AMAS. We will use the frequently used AMAS with nine items contributing to two scales: Math Learning and Math Testing. AMAS originates from a reanalysis of a MARS-R by Hopko et al. (2003). AMAS is short (completion takes about 5 minutes) and has good psychometric properties: high reliability as measured by internal consistency and test-retest method, construct validity as measured by exploratory and confirmatory factor analyses, and convergent and discriminant validity. (Numerous subsequent studies have confirmed these results.) We will use AMAS to measure math anxiety in this project.

  2. Multi-item Survey Instrument for Math Self-efficacy. Math anxiety and math self-efficacy are negatively correlated. The three-item short version of math self-efficacy questionnaires: (1) I usually understand a mathematical idea quickly; (2) I have to work very hard to understand mathematics; (3) I can connect mathematical ideas that I have learned; used by Rozgonjuk et al. (2020).

  3. Multi-item Survey Instrument for Student’s Perception on Faculty Teaching Strategies: Students’ mathematics anxiety is directly influenced by their instructors’ teaching strategies. This study employs the Teaching Strategies Inventory used by Cardino Jr. and Ortega-Dela Cruz (2020) to assess students’ perceptions of these strategies. The inventory comprises eight distinct dimensions (subscales).

  4. Multi-item Survey Instrument for Student Learning Modalities: AVID (Advancement Via Individual Determination) is a program introduced by Meadowlark Elementary School that aims to close the achievement gap by preparing all students for college readiness and success in a global society. We used AVID’s Student Learning Modality Inventory to identify student learning styles (auditory, visual, and kinesthetic) in this study. The inventory can be found at https://pengdsci.github.io/MathAnxiety/AVID_Learning_Style_Inventory.pdf.

  5. Multi-item Survey Instrument for Student’s Engagement: We select 12 questionnaires from the NSSE (National Survey of Student Engagement) to assess students in-class and after-class engagement and use of learning resources. The The core NSSE survey for a first-year or senior student consists of approximately 40 to 50 required items, but the total bank of potential questions is much larger. The complet instrument can be found at https://nsse.indiana.edu/nsse/survey-instruments/us-english.html.

  6. Single-item questions: These questions capture demographic information.

5 Raw Data Processing

At the end of data collection, we received 895 responses. Of these, 199 participants did not complete the main survey subscales. The analysis is based on the remaining 696 responses for which the main subscales were completed, which contained only a few missing values. Several redundant variables were removed from the raw data. In addition, some original categorical variables were recategorized to avoid sparse groups and improve interpretability.

5.1 Missing Value Imputation

To main this sample size, we use random imputation approach to fill in the missing values. Since all multi-item sub-scales were measured using a Likert scale, the scores follows a multinomial distribution. The empirical distribution will be used in the random imputation to main the probability distribution of the observed data. The following code imputes the missing values in all multi-item subscales.

Imputation = function(DataName){
  for (i in 1:(dim(DataName)[2])){
    vec = as.vector(DataName[, i])
    na.id = which(is.na(vec))
    n0 = length(na.id)
    prob0 = table(vec)/length(vec)
    imput.val = NULL
      for (j in 1:n0){
      imput.val[j] = sample(1:length(prob0), size = 1, prob = prob0)
    }
    DataName[na.id, i] = imput.val
  }
   DataName
}

5.2 Reverse Scoring

Reverse scoring is a crucial data preparation step for multi-item surveys where some items are worded in the opposite direction to prevent response bias. After item-wise review of all instruments along with statistical procedures of correlation and confirmatory factor analysis (CFA), item 2 in the Self-efficacy Instrument and all questions except items 5 and 7 in the Technology Instrument were negatively worded. The scores of these items were reversed.

In addition, all questions regarding engagement and resource use were reverse-worded, so their scores were reversed for the subsequent analysis.

5.3 Sparse Category Regrouping

Two variables need to be regrouped in the following: course level and ethnicity.

  • MathCourseLevel
    • Math.I: MATQ30, MAT100, MAT101, MAT102,
    • Math.II: MAT193, MAT104, MAT112, MAT113, MAT115, MAT131
    • Math.III: MAT143, MAT145, MAT151, MAT161
    • Math.IV: MAT162-MAT480
    • Stats: MAT121, MAT125, STA200
    • Other: All courses not listed above
  • Ethnicity
    • White
    • Black: Black and African American
    • Asian
    • Other: Native Hawaiian or Pacific Islander, Multiple Ethnicity or Other, Prefer Not To Answer
  • Learning Modalities
df_with_freq <- Comp.Modality %>%
  rowwise() %>%
  mutate(
    freq_A = sum(c_across(MS.1:MS.12) == "1"),
    freq_B = sum(c_across(MS.1:MS.12) == "2"),
    freq_C = sum(c_across(MS.1:MS.12) == "3")
  ) %>%
  ungroup()
###
df_with_freq$max_freq_col <- names(df_with_freq)[max.col(df_with_freq[, c("freq_A", "freq_B", "freq_C")]) + 1]
df_with_freq$max_freq_value <- apply(df_with_freq[, c("freq_A", "freq_B", "freq_C")], 1, max)
df_with_freq$modality <- ifelse(df_with_freq$max_freq_col=="MS.1", "Auditory", 
                                ifelse(df_with_freq$max_freq_col=="MS.2", "Visual", "Kinesthetic"))

5.4 Exploratory Factor Analysis (EFA) on Anxiety

The abbreviated mathematical anxiety (MA) instrument developed by Hopko et al. (2003) is characterized by a two-factor structure that divides into two subscales: mathematics evaluation anxiety (MEA) and mathematics learning anxiety (MLA). The subsequent exploratory factor analysis serves to validate this construct.

# Check correlations (visually)
n = dim(Comp.Anxiety[,-1])[1]
cor_matrix <- cor(Comp.Anxiety[,-1])
#corPlot(cor_matrix, upper = FALSE)
# Bartlett's Test of Sphericity (we want a significant p-value, p < .05)
cortest.bartlett(cor_matrix, n = n)

# KMO Measure of Sampling Adequacy (MSA) (We want overall MSA > 0.6, ideally > 0.8)
KMO(cor_matrix)

Bartlett’s test of sphericity produced a statistically significant result (p < .001), confirming that the variables are sufficiently correlated to proceed with factor analysis. The Kaiser-Meyer-Olkin (KMO) Measure of Sampling Adequacy, with both overall and item-level values exceeding 0.80, indicates that the data contain adequate common variance to warrant factor analysis. Furthermore, the scree plot clearly demonstrates the anticipated two-factor structure of the construct.

# Get eigenvalues
fa_result <- fa(Comp.Anxiety[,-1], nfactors = ncol(Comp.Anxiety[,-1]), rotate = "none")
eigenvalues <- fa_result$e.values

# Scree plot with horizontal line using shapes
scree_plot <- plot_ly(x = 1:length(eigenvalues), y = eigenvalues,
                      type = 'scatter', mode = 'lines+markers',
                      line = list(width = 3),
                      marker = list(size = 8)) %>%
  layout(
    title = "Scree Plot with Kaiser Criterion (Eigenvalue)",
    xaxis = list(title = "Factor Number"),
    yaxis = list(title = "Eigenvalue"),
    shapes = list(
      list(
        type = "line",
        x0 = 0,
        x1 = length(eigenvalues),
        y0 = 1,
        y1 = 1,
        line = list(color = "red", width = 2, dash = "dash")
      )
    ),
    annotations = list(
      list(
        x = length(eigenvalues) * 0.8,
        y = 1.1,
        text = "Kaiser Criterion (λ = 1)",
        showarrow = FALSE,
        font = list(color = "red")
      )
    ),
     margin = list(
                  t = 100,  # Adjust this value to increase or decrease the top margin
                  b = 50,
                  l = 50,
                  r = 50)
  )

scree_plot

Next, we perform EFA to identify the items of MEA and MLA through factor loadings.

## two-factor aEFA
efa_2factor <- fa(Comp.Anxiety[,-1], nfactors = 2, rotate = "oblimin", 
                  fm = "pa", scores = "regression")
# Create a clean loadings table
loadings_table <- fa.sort(efa_2factor$loadings[])
pander(loadings_table, digits = 2, cutoff = 0.3)
  PA1 PA2
AMAS.2 0.83 0.061
AMAS.4 0.8 0.054
AMAS.8 0.78 -0.13
AMAS.5 0.56 0.12
AMAS.3 -0.024 0.74
AMAS.7 -0.059 0.71
AMAS.6 0.045 0.69
AMAS.9 0.13 0.64
AMAS.1 0.013 0.5

As shown in the table above, items 2, 4, 5, and 8 load onto the evaluation anxiety factor, whereas the remaining items load onto the learning anxiety factor. Two distinct subscales will be established for subsequent analyses.

Anxiety.mea <- Comp.Anxiety[, c("ID",  "AMAS.2", "AMAS.4", "AMAS.5",  "AMAS.8")]
Anxiety.mla <- Comp.Anxiety[, c("ID", "AMAS.1", "AMAS.3", "AMAS.6", "AMAS.7", "AMAS.9")]

6 Validation and Reliability

The major multi-item instruments used in this study are well-established and have been used in various published research. In practice, the validity and reliability of such established instruments must be confirmed before any statistical analysis. We next perform reliability and validity analyses to warrant the credibility of the overall survey design and the quality of the collected data.

6.1 Validity Analysis

Validity of a multi-item survey instrument answers the question: “Am I actually measuring what I intend to measure?” It’s about the soundness of the interpretation of the scores. In psychometrics, validity refers to the degree to which a scale measures what it claims to measure. For a single-factor instrument, this means all items are indicators of one underlying construct such as maths anxiety, self-efficacy, engagement, etc. in this comprehensive survey. The CFA has been used in survey research widely, see Watson, et al (1988) and Marsh (1996).

Confirmatory Factor Analysis (CFA) is a powerful statistical technique used to test a pre-specified theory about the structure of your instrument. We use CFA to confirm that your hypothesized single-factor model is consistent with the observed data. It provides rigorous evidence for construct validity in a list of conventional measures:

  • Factor Loadings are the standardized weights from the Confirmatory Factor Analysis (CFA). The suggested guidelines are:

    • A loading magnitude greater than 0.5 indicates that the item shares at least 25% of its variance with the latent factor. In the following table, we report the minimum loading for each instrument under the column std.all.min.
    • All loadings must be statistically significant (p < 0.05). We report the maximum p-value for each instrument under the column pval.max.
  • Standardized Root Mean Square Residual (SRMR) measures the goodness-of-fit of the CFA model. It represents the average standardized residual between the observed and predicted correlation matrices. A lower value indicates a better fit, with a suggested cutoff of less than 0.08.

  • Comparative Fit Index (CFI) is another goodness-of-fit measure for the CFA. It compares the specified model to a null (independence) model. A higher value indicates a better fit, with a suggested cutoff of greater than 0.9.

  • Tucker-Lewis Index (TLI) also measures the goodness-of-fit of the CFA. Its interpretation and usage are similar to those of the CFI.

After some exploratory analysis, we dropped a few items from the Technology Instrument and defined two sucscales of the initial resource instruments: use of resource and student engagement.

The final results on the struct validity measures are summarized in the following table.

cfa.analysis <- function(dataset){
  #dataset <- Comp.Anxiety
  predictors <- names(dataset[, -1])  
  n0 <- length(predictors)
  cfa.model <-  paste("latent =~", paste(predictors, collapse = " + "))
  cfa.fit <- cfa(cfa.model, data = dataset[, -1], estimator = "MLM")
  results <- summary(cfa.fit, standardized = TRUE, fit.measures = TRUE, rsquare = TRUE)
  std.all.min <- min(results$pe$std.lv[1:n0])
  pval.max <- max(results$pe$pvalue[2:n0])
  srmr <- results$fit["srmr"]
  cfi <- results$fit["cfi"]
  tli <- results$fit["tli"]
  #rmsea <- results$fit["rmsea"]
  cbind(std.all.min = std.all.min, pval.max = pval.max, srmr = srmr, cfi = cfi,  tli = tli)
}
anxiety.mea.vlid <-cfa.analysis(Anxiety.mea)
anxiety.mla.vlid <-cfa.analysis(Anxiety.mla)
anxiety.vlid <-cfa.analysis(Comp.Anxiety)
efficacy.vlid <-cfa.analysis(Comp.SelfEfficacy)
tech.vlid <-cfa.analysis(Comp.Technology)
cooperative.vlid <-cfa.analysis(Comp.Cooporative)
deductive.vlid <-cfa.analysis(Comp.Deductive)
demo.vlid <-cfa.analysis(Comp.Demonstration)
inductive.vlid <-cfa.analysis(Comp.Inductive)
integrate.vlid <-cfa.analysis(Comp.Integrative)
lecture.vlid <-cfa.analysis(Comp.LectureType)
repetive.vlid <-cfa.analysis(Comp.Repetitive)
engage.vlid <-cfa.analysis(Comp.Engage)
resource.vlid <-cfa.analysis(Comp.Resource)
##
vlid.table <-rbind(anxiety.mea = anxiety.mea.vlid, anxiety.mla = anxiety.mla.vlid, 
                  anxiety = anxiety.vlid, self.efficacy = efficacy.vlid,
                  technology = tech.vlid, cooperative = cooperative.vlid,
                  deductive = deductive.vlid, demonstration = demo.vlid,
                  inductive = inductive.vlid, integrate = integrate.vlid,
                  lecture = lecture.vlid, repetitive = repetive.vlid, 
                  engage = engage.vlid, resource = resource.vlid)
row.name <- c("anxiety.mea", "anxiety.mla", "anxiety", "self.efficacy", 
              "technology", "cooperative",
              "deductive", "demonstration", "inductive", "integrate",
              "lecture", "repetitive", "engage", "resource")
col.name <- c("std.all.min", "pval.max", "srmr", "cfi",  "tli")
rownames(vlid.table) <- row.name
colnames(vlid.table) <- col.name
pander(vlid.table)
  std.all.min pval.max srmr cfi tli
anxiety.mea 0.7244 0 0.04544 0.9674 0.9021
anxiety.mla 0.4804 0 0.02092 0.9899 0.9798
anxiety 0.4166 0 0.08501 0.8152 0.7536
self.efficacy 0.4797 2.464e-06 2.169e-09 1 1
technology 0.5089 0 0.08141 0.8235 0.7731
cooperative 0.8847 0 0.04424 0.9337 0.8894
deductive 0.7555 0 0.04682 0.9462 0.9193
demonstration 0.7079 0 0.0375 0.9569 0.9353
inductive 0.7378 0 0.03004 0.9712 0.9568
integrate 0.487 0 0.05739 0.9157 0.8735
lecture 0.7208 0 0.02609 0.9776 0.9663
repetitive 0.5762 0 0.05573 0.9084 0.8627
engage 0.6855 0 5.435e-09 1 1
resource 0.4235 0 0.07786 0.865 0.5951

The construct validity of all multi-item instruments was assessed using Confirmatory Factor Analysis (CFI). The results confirmed that most scales meet established psychometric standards. The mojprity of the key fit indices, including CFI and TLI, exceeded the recommended threshold of 0.90, while the SRMR fell below the 0.08 cutoff, indicating a good model fit. Furthermore, all factor loadings were statistically significant (p < .05) and substantial in magnitude (exceeding 0.4), demonstrating strong relationships between the items and their intended latent constructs. In summary, the validity analysis confirms that the instruments used in this study are robust and appropriate for measuring their respective concepts.

Remarks: (1). The above validity measures based on the items follow multi-variate normal distribution, This is a strong assumption. The items in each instrument are not continous. This influences some of the validity measure. (2). In practice, we can use some descriptive approaches to visual check with assuming multi-variate normality.

6.2 Relianbility Analysis

Reliability of a multi-item survey instrument answers the question: “If I measure the same thing multiple times, will I get a consistent result?” It measures how well the items that are supposed to measure the same construct hang together.

Internal Consistency is the most common assessment for a survey administered once. It measures the degree to which items in a scale are correlated with each other. Two well-known internal consistency measures are Cronbach’s Alpha (Cronabck, 1951) and McDonald’s Omega (1999). McDonald’s Omega is more robust than Cronbach’s Alpha.

Cronbach’s Alpha and McDonald’s Omega typically range from 0 to 1. The suggested cut-offs are given below.

  • > 0.9: Excellent

  • 0.8 - 0.9: Good

  • 0.7 - 0.8: Acceptable

  • < 0.7: Poor (may have items that don’t “belong”)

anxiety.mea.rel <- Reliability.fun(Anxiety.mea)
anxiety.mla.rel <- Reliability.fun(Anxiety.mla)
anxiety.rel <- Reliability.fun(Comp.Anxiety)
efficacy.rel <- Reliability.fun(Comp.SelfEfficacy)
tech.rel <- Reliability.fun(Comp.Technology)
cooperative.rel <- Reliability.fun(Comp.Cooporative)
deductive.rel <- Reliability.fun(Comp.Deductive)
demo.rel <- Reliability.fun(Comp.Demonstration)
inductive.rel <- Reliability.fun(Comp.Inductive)
integrate.rel <- Reliability.fun(Comp.Integrative)
lecture.rel <- Reliability.fun(Comp.LectureType)
repetive.rel <- Reliability.fun(Comp.Repetitive)
#after.rel <- Reliability.fun(Comp.AfterClass)
#in.class.rel <- Reliability.fun(Comp.InClass)
engage.rel <- Reliability.fun(Comp.Engage)
resource.rel <- Reliability.fun(Comp.Resource)
##
Rel.table <-rbind(anxiety.mea = anxiety.mea.rel, anxiety.mla = anxiety.mla.rel,
                  anxiety = anxiety.rel, self.efficacy = efficacy.rel,
                  technology = tech.rel, cooperative = cooperative.rel,
                  deductive = deductive.rel, demonstration = demo.rel,
                  inductive = inductive.rel, integrate = integrate.rel,
                  lecture = lecture.rel, repetitive = repetive.rel, 
                  engage = engage.rel, resource = resource.rel)
row.name <- c("anxiety.mea", "anxiety.mla",
              "anxiety", "self.efficacy", "technology", "cooperative",
              "deductive", "demonstration", "inductive", "integrate",
              "lecture", "repetitive", "engage", "resource")
col.name <- c("Cronbach alpha", "McDonald's Omega")
rownames(Rel.table) <- row.name
colnames(Rel.table) <- col.name
pander(Rel.table)
  Cronbach alpha McDonald’s Omega
anxiety.mea 0.8413 0.846
anxiety.mla 0.802 0.8052
anxiety 0.8638 0.866
self.efficacy 0.6631 0.7165
technology 0.9261 0.9282
cooperative 0.8875 0.8875
deductive 0.8778 0.8788
demonstration 0.8821 0.8825
inductive 0.8899 0.8904
integrate 0.8276 0.8314
lecture 0.8992 0.9009
repetitive 0.8877 0.8891
engage 0.8349 0.8351
resource 0.7474 0.7518

We can see from the above table that all calculated coefficients exceeded the recommended threshold of 0.7, indicating good reliability. The results confirm that the instruments used in this study demonstrate strong internal consistency, meaning the items within each scale reliably measure the same underlying construct.

7 Composite Scoring

The core purpose of constructing multi-item surveys is to measure complex concepts with greater accuracy, reliability, and depth than a single question ever could. All instruments used in this study are based on a single-factor construct using the Likert scales. The commonly used methods for defining single index to capture the information of the single-factor construct are classified in three categories

7.1 Summing the Raw Likert Scores

The simplest approach is to sum the raw Likert scores into a composite score that represents a single factor within the survey construct. This method is valid provided that all questionnaire items are equally important, as each captures a similar amount of information about the underlying factor.

However, this approach is violated in several critical scenarios, leading to a biased and unreliable composite score. For example, Violation of Equal Importance: The core assumption is that each item is a equally strong indicator of the construct. In reality, items often have different levels of importance. Summing items with high and low levels of importance equally gives undue weight to weaker indicators, effectively diluting the composite score with noise and reducing its validity.

7.2 FA Approach

Confirmatory Factor Analysis (CFA) is a very common and often practical approach to validating survey instruments and create (weighted) composite score. It is a distribution dependent statistical method. However, it comes with a set of distinct some disadvantages particularly the assumption of multi-variate normal distribution. Factor loadings in CFA are estimated based on the maximum likelihood which is defined based on multivariate normal distribution.

We have used CFA to validate the instrument. Since all instruments in this study are single-factor constructs, we will calculate the single composite score for each instrument using CFA.

7.3 PCA Approach

PCA is a distribution-free method which uses a mathematical transformation (orthogonal rotation) to obtain a new coordinate system such that the first new axis (Principal Component 1) points in the direction of the maximum variance in the data. The second axis is orthogonal to the first and points in the direction of the next greatest variance, and so on. The new axes (components) are linear combinations of the original variables. Consequently, a k-item instrument will generate k principal components.

Although there debates on using PCA in psychometrics, the earliest applications of PCA in survey research can be traced back to 1950s (Stouffer et al., 1950; Cattell, 1952; Duncan, 19 ). The goal was consistently the same as it is today: to uncover the simple, latent structures that underlie the complex correlations among many observed survey questions.

Adjusting Direction of PCs

Principal Components (PCs) are new, uncorrelated axes, whereas Likert scores are ordinal rating scales. When using PCs to represent these rating scales, their direction must be aligned. A simple method to determine if a PC’s direction needs to be reversed is to examine the correlation coefficients between the naive composite average scores and the PC scores. If the correlation is negative, the corresponding PC should be reversed; otherwise, the default axis should be retained.

Composite Scoring Using The first Principal Component (PC1)

This approach has been employed since the 1950s (e.g., Guttman, 1954; Hirschberg & Standish, 1959; Duncan, 1961). The rationale for using the first principal component is that it accounts for the maximum variance in the data and constitutes a linear combination of all items. Much like in confirmatory factor analysis (CFA), the first principal component can be interpreted as a weighted average of individual item scores.

Composite Scoring Using Weighted Average of Item Scores Across All PCs: Doubly Weighted Average

In many real-world datasets, the underlying constructs are inherently multidimensional. Consequently, limiting the analysis to the first principal component means discarding structured information captured by subsequent components (PC2, PC3, etc.). A composite score that integrates all significant components offers a more holistic and accurate summary measure. The primary barrier to the widespread adoption of this method is the challenge associated with interpreting the composite index’s structure.

7.4 Composite Scores To Be Created

We will generate four types of composite scores for each of the 11 instruments for the purpose of empirical comparison.

  • avg: The average of the raw item scores.
  • cfa: The extract confirmatory factor analysis (cfa) score (all instruments are based on the single-factor construct).
  • pca1: The first principal component scores.
  • pca.wt: The weighted average of pca scores across all principal components.
#####
 scores = function(df, dn){
  ###############
  # mean score
  ##############
  df.mean <- rowMeans(df[, -1])
  ###########################
  ## single factor score
  ##########################
  x.var <- names(df[, -1])
  n0 <- length(x.var)
  cfa.model <-  paste("latent =~", paste(x.var, collapse = " + "))
  cfa.fit <- cfa(cfa.model, data = df[, -1], estimator = "MLM")
  composite.cfa <- lavPredict(cfa.fit)
  ##########################
  # pca analysis
  ##########################
  pca.mdl <- prcomp(df[,-1], scale = TRUE)
  pca0 <- pca.mdl$x[, 1]
  r0 = cor(pca0, df.mean)
  if(r0 < 0) {
     pca.all <- -pca.mdl$x
  }else{
    pca.all <- pca.mdl$x
  }
  first.pca = pca.all[,1]
  ##########################
  # weighted pca score
  ##########################
  var.explained <-((pca.mdl$sdev)^2) / sum((pca.mdl$sdev)^2) #
  composite_weighted_pca <- as.matrix(pca.all) %*% (var.explained)

  outdata <- as.data.frame(cbind(avg = df.mean, 
                           pca1 = first.pca, 
                           wt.pca = as.vector(composite_weighted_pca), 
                           cfa = as.vector(composite.cfa)))
  names(outdata) <- paste0(dn,".", names(outdata), sep = "")
  outdata
  }
###
Anxiety.mea.score = scores(Anxiety.mea, "Anxiety.mea")
Anxiety.mla.score = scores(Anxiety.mla, "Anxiety.mla")
Anxiety.score = scores(Comp.Anxiety, "Anxiety")
SelfEfficacy.score = scores(Comp.SelfEfficacy0, "SelfEfficacy")
Technology.score = scores(Comp.Technology, "Technology")
Cooporative.score = scores(Comp.Cooporative, "Cooporative")
Deductive.score = scores(Comp.Deductive, "Deductive")
Demonstration.score = scores(Comp.Demonstration, "Demonstration")
Inductive.score = scores(Comp.Inductive, "Inductive")
Integrative.score = scores(Comp.Integrative, "Integrative")
LectureType.score = scores(Comp.LectureType, "LectureType")
Repetitive.score = scores(Comp.Repetitive, "Repetitive")
Engage.score = scores(Comp.Engage, "Engage")
Resource.score = scores(Comp.Resource, "Resource")
##
finalDat <- cbind(demographics, Anxiety.score, Anxiety.mea.score,
                  Anxiety.mla.score, SelfEfficacy.score, Technology.score,
                  Cooporative.score, Deductive.score, Demonstration.score,Inductive.score,
                  Integrative.score, LectureType.score, Repetitive.score,
                  Engage.score, Resource.score)

8 Some Graphical Exploration

We next explore the distributions of the created composite scores and perform some empirical comparisons. The primary goal of this survey study is to investigate factors that are associated with mathematics anxiety (MA) levels. To this end, we also look the distributions each individual items in the MA instrument.

8.1 Distributions of Composite Scores

The following are distributions of four generated composite scores across all instruments. The purpose is to examine the behaviors of these composite scores, especially the doubly weighted composite score based on the principal component analysis.

plotly.fun <- function(in.data){
   in.avg <- density(in.data[,1])
   in.pc1 <- density(in.data[,2])
   in.pcw <- density(in.data[,3])
   in.cfa <- density(in.data[, 4])
   dat.name <- sub("\\..*", "",names(in.data)[1])  #sub( text)
   # plot density curves
  fig <- plot_ly(x = ~in.avg$x, y = ~in.avg$y, 
               type = 'scatter', 
               mode = 'lines', 
               name = 'avg', 
               fill = 'tozeroy')  %>% 
           # adding more density curves
       add_trace(x = ~in.pc1$x, y = ~in.pc1$y, 
                 name = 'pca1', 
                 fill = 'tozeroy')  %>% 
       add_trace(x = ~in.pcw$x, y = ~in.pcw$y, 
                 name = 'pca.wt', 
                 fill = 'tozeroy')  %>% 
       add_trace(x = ~in.cfa$x, y = ~in.cfa$y, 
                 name = 'cfa', 
                 fill = 'tozeroy')  %>% 
       layout(xaxis = list(title = 'scores'),
              yaxis = list(title = 'Density'),
              #title = dat.name,
               margin = list(
                  t = 100,  # Adjust this value to increase or decrease the top margin
                  b = 50,
                  l = 50,
                  r = 50)
             )
     fig
     }
####
in.anxiety.mea = final.anxiety.dat[, c( "Anxiety.mea.avg", "Anxiety.mea.pca1", "Anxiety.mea.wt.pca","Anxiety.mea.cfa")]
in.anxiety.mla = final.anxiety.dat[, c("Anxiety.mla.avg","Anxiety.mla.pca1", "Anxiety.mla.wt.pca","Anxiety.mla.cfa")]
###
in.anxiety = final.anxiety.dat[, c( "Anxiety.avg", "Anxiety.pca1", "Anxiety.wt.pca", "Anxiety.cfa")]
in.efficacy = final.anxiety.dat[, c( "SelfEfficacy.avg", "SelfEfficacy.pca1","SelfEfficacy.wt.pca","SelfEfficacy.cfa")]
in.technology = final.anxiety.dat[, c( "Technology.avg","Technology.pca1", "Technology.wt.pca","Technology.cfa")]
in.cooporative = final.anxiety.dat[, c("Cooporative.avg","Cooporative.pca1", "Cooporative.wt.pca","Cooporative.cfa")]
in.deductive = final.anxiety.dat[, c("Deductive.avg","Deductive.pca1","Deductive.wt.pca","Deductive.cfa")]
in.demonstration = final.anxiety.dat[, c("Demonstration.avg","Demonstration.pca1","Demonstration.wt.pca","Demonstration.cfa")]
in.inductive = final.anxiety.dat[, c( "Inductive.avg","Inductive.pca1","Inductive.wt.pca","Inductive.cfa")]
in.integrative = final.anxiety.dat[, c( "Integrative.avg", "Integrative.pca1","Integrative.wt.pca","Integrative.cfa")]
in.lectureType = final.anxiety.dat[, c( "LectureType.avg", "LectureType.pca1", "LectureType.wt.pca","LectureType.cfa")]
in.repetitive = final.anxiety.dat[, c( "Repetitive.avg", "Repetitive.pca1", "Repetitive.wt.pca","Repetitive.cfa")]
in.engage = final.anxiety.dat[, c(  "Engage.avg", "Engage.pca1", "Engage.wt.pca","Engage.cfa")]
in.resource = final.anxiety.dat[, c( "Resource.avg", "Resource.pca1", "Resource.wt.pca", "Resource.cfa")]
p.mea <- plotly.fun(in.anxiety.mea)
p.mla <- plotly.fun(in.anxiety.mla)
# Arrange in 1x2 grid
subplot(p.mea, p.mla, nrows = 1, titleX = TRUE, titleY = TRUE, margin = 0.1) %>%
  layout(
    annotations = list(
      list(x = 0.05, y = .99, text = "Anxiety.mea", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.75, y = 0.99, text = "Anxiety.mla", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
    ),
    showlegend = FALSE
  )
p1 <- plotly.fun(in.anxiety)
p2 <- plotly.fun(in.efficacy)
p3 <- plotly.fun(in.technology)
p4 <- plotly.fun(in.cooporative)
# Arrange in 2x2 grid
subplot(p1, p2, p2, p4, nrows = 2, titleX = TRUE, titleY = TRUE, margin = 0.1) %>%
  layout(
    annotations = list(
      list(x = 0.05, y = .99, text = "Anxiety", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.75, y = 0.99, text = "Self-efficacy", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.05, y = 0.4, text = "Technology", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.75, y = 0.4, text = "Coorporative", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
    ),
    showlegend = FALSE
  )
p1 <- plotly.fun(in.deductive)
p2 <- plotly.fun(in.demonstration)
p3 <- plotly.fun(in.inductive)
p4 <- plotly.fun(in.integrative)
# Arrange in 2x2 grid
subplot(p1, p2, p2, p4, nrows = 2, titleX = TRUE, titleY = TRUE, margin = 0.1) %>%
  layout(
    annotations = list(
      list(x = 0.05, y = .99, text = "Deductive", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.75, y = 0.99, text = "Demonstrative", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.05, y = 0.4, text = "Inductive", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.75, y = 0.4, text = "Intergrative", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
    ),
    showlegend = FALSE
  )
p1 <- plotly.fun(in.lectureType)
p2 <- plotly.fun(in.repetitive)
p3 <- plotly.fun(in.engage)
p4 <- plotly.fun(in.resource)
# Arrange in 2x2 grid
subplot(p1, p2, p2, p4, nrows = 2, titleX = TRUE, titleY = TRUE, margin = 0.1) %>%
  layout(
    annotations = list(
      list(x = 0.05, y = .99, text = "Lecture Type", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.75, y = 0.99, text = "Repetative", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.05, y = 0.4, text = "Engagement", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.75, y = 0.4, text = "Resource", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
    ),
    showlegend = FALSE
  )

These density curves illustrate the distributions of the four composite scores (avg, cfa, pc1, and pca.wt) for all single-factor instruments in the survey. The avg is a naive measure, derived from the arithmetic mean of the item scores. The cfa and pc1 composites are weighted averages, where the weights (loadings) are derived from distinct latent variable models. The pca.wt composite is a doubly weighted average, based on both the original item scores and all of the resulting principal components.

  • Three model-based composite scores (cfa, pc1, and pca.wt) are centered at 0 but exhibit different behaviors:
    • pc1 has the largest variance.
    • cfa has the smallest variance.
  • avg and pca.wt behave similarly, differing primarily in their locations.

The composite score avg serves as a reference point, analogous to an empirical distribution, as it uses all item scores directly. In contrast, pca.wt uses a doubly weighted average of all item scores without imposing complex distributional assumptions. This demonstrates that pca.wt is a reliable and robust composite score. For the remainder of this report, the pca.wt score will be used, with cfa occasionally employed for illustrative purposes for some special cases.

8.2 Distribution of Demographics

The distribution of demographic factors are reported in the following figures.

# Enhanced hover information
Demographic.bar <-function(in.cat, varname){
  freq.tbl <- table(in.cat)
  df <- data.frame(
      category <- names(freq.tbl),
      values <- as.vector(freq.tbl)
  )
  # High-contrast colors (manually defined)
  accessible_colors <- c(
  '#D55E00',  # Vermillion
  '#0072B2',  # Blue
  '#F0E442',  # Yellow
  '#009E73',  # Green
  '#56B4E9',  # Sky Blue
  '#E69F00',  # Orange
  '#CC79A7'   # Pink
  )
  fig <- plot_ly(df, x = ~category, y = ~values, type = 'bar',
                hoverinfo = 'text',
               text = ~paste('Category:', category, '<br>Value:', values, '<br>Percentage:', round(values/sum(values)*100, 1), '%'),
               #text = ~paste("Value:", values), 
               textposition = 'auto',
               marker = list(
                 color = accessible_colors[1:nrow(df)],
                 line = list(color = 'black', width = 2)
               ),
               textfont = list(color = 'white', size = 12)) %>%
   layout(
   # title = list(text = varname, 
                # font = list(size = 18, color = 'black')),
    xaxis = list(title = "Categories", 
                 tickfont = list(color = 'black')),
    yaxis = list(title = "Values", 
                 gridcolor = 'lightgray',
                 tickfont = list(color = 'black')),
    plot_bgcolor = 'white',
    paper_bgcolor = 'white',
    showlegend = FALSE,
    margin = list(
                  t = 100,  # Adjust this value to increase or decrease the top margin
                  b = 50,
                  l = 50,
                  r = 50)
  )
fig
}
in.cat.sex <-  final.anxiety.dat$sex
in.cat.race <-  final.anxiety.dat$race
in.cat.class <-  final.anxiety.dat$class
in.cat.major <-  final.anxiety.dat$major
in.cat.math.level <-  final.anxiety.dat$math.level
in.cat.modality <-  final.anxiety.dat$modality
##
g.sex <- Demographic.bar(in.cat.sex, "Gender Distribution")
g.race <- Demographic.bar(in.cat.race, "Racial Distribution")
g.class <- Demographic.bar(in.cat.class, "Class Distribution")
g.major <- Demographic.bar(in.cat.major, "Major Distribution")
g.math.level <- Demographic.bar(in.cat.math.level, "Math Course Level")
g.modality <- Demographic.bar(in.cat.modality, "Learning Modality")
# Arrange in 2x2 grid
subplot(g.sex, g.race, g.class, g.major, nrows = 2, titleX = FALSE, titleY = TRUE, margin = 0.1) %>%
  layout(
    annotations = list(
      list(x = 0.35, y = .99, text = "Gender", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.75, y = 0.99, text = "Race", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.35, y = 0.4, text = "Class Level", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.75, y = 0.4, text = "Major", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
    ),
    showlegend = FALSE
  )
# Arrange in 2x2 grid
subplot(g.math.level, g.modality, nrows = 1, titleX = FALSE, titleY = TRUE, margin = 0.1) %>%
  layout(
    annotations = list(
      list(x = 0.35, y = .99, text = "Math Course Level", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14)),
      list(x = 0.75, y = 0.99, text = "Learning Modality", 
           xref = "paper", yref = "paper", showarrow = FALSE, font = list(size = 14))
    ),
    showlegend = FALSE
  )

Only one category in variable class is less than 3% with 21 observations. Other variables don’t have issues on sparse categories.

8.3 Relationship Between Math Anxiety and Demographic Factors

A student’s demographic profile doesn’t determine their math anxiety, but it significantly influences which type of anxiety they are most vulnerable to and why. The next subsections present visual explorations of the relationship between demographic factors and the two dimensions of mathematical anxiety.

8.3.1 Mathematical Evaluation Anxiety

This is the anxiety a student feels when their mathematical ability is being formally or informally assessed. The primary fear is not of the math itself, but of the negative consequences of performing poorly. It’s performance-oriented. The stress comes from the situation of being evaluated, not necessarily from the content.

## plotly for anxiety vs gender and other categorical demographic factor
gender.plotly <- function(in.var1, in.var2){
      gender.anxiety <- plot_ly(final.anxiety.dat, 
                              x = ~sex, 
                              y = ~Anxiety.mea.wt.pca, 
                              color = as.formula(paste0("~",in.var1)),
                              type = "box",
                              boxpoints = "no",
                              jitter = 0.3,
                              pointpos = 0,
                              hoverinfo = "y + x + name",
                              hovertext = ~paste("Group:", in.var1,
                                                "<br>Factor:", sex,
                                                "<br>Score:", round(Anxiety.mea.wt.pca, 2)),
                              marker = list(size = 5, opacity = 0.7)) %>%
    layout(title = paste("Math Evaluation Anxiety (wt.PCA): Gender vs ", in.var2,""),
         xaxis = list(title = ""),
         yaxis = list(title = "Evaluation Anxiety Score"),
         boxmode = "group",
         hoverlabel = list(bgcolor = "white", font = list(size = 12)),
         margin = list(
                  t = 100,  # Adjust this value to increase or decrease the top margin
                  b = 50,
                  l = 50,
                  r = 50)
         )

 gender.anxiety 
}
gender.math.level = gender.plotly("math.level", "Math Course Level")
gender.math.level
gender.race = gender.plotly("race", "Race")
gender.race
gender.class = gender.plotly("class", "Class")
gender.class
gender.major = gender.plotly("major", "Major")
gender.major
gender.modality = gender.plotly("modality", "Modality")
gender.modality

Some of the patterns observed in this study are consistent with the existing literature.

  • Female students have relatively higher evaluation anxiety level than male students.
  • The discrepancy of evaluation anxiety level across ethnic groups also consistent with what reported in the existing literature.

8.3.2 Mathematical Learning Anxiety

Mathematical learning anxiety stems directly from the subject matter, where the primary source of distress is the act of engaging with mathematical concepts. This engagement triggers an internal state of confusion, frustration, and cognitive overload.

The next few figures examine the relationship between mathematical learning anxiety and demographic factors, using the same visual approach as we did for mathematical evaluation anxiety.

## plotly for anxiety vs gender and other categorical demographic factor
gender.plotly <- function(in.var1, in.var2){
      gender.anxiety <- plot_ly(final.anxiety.dat, 
                              x = ~sex, 
                              y = ~Anxiety.mla.wt.pca, 
                              color = as.formula(paste0("~",in.var1)),
                              type = "box",
                              boxpoints = "no",
                              jitter = 0.3,
                              pointpos = 0,
                              hoverinfo = "y + x + name",
                              hovertext = ~paste("Group:", in.var1,
                                                "<br>Factor:", sex,
                                                "<br>Score:", round(Anxiety.mla.wt.pca, 2)),
                              marker = list(size = 5, opacity = 0.7)) %>%
    layout(title = paste("Math Learning Anxiety (wt.PCA): Gender vs ", in.var2,""),
         xaxis = list(title = ""),
         yaxis = list(title = "Learning Anxiety Score"),
         boxmode = "group",
         hoverlabel = list(bgcolor = "white", font = list(size = 12)),
         margin = list(
                  t = 100,  # Adjust this value to increase or decrease the top margin
                  b = 50,
                  l = 50,
                  r = 50)
         )

 gender.anxiety 
}
gender.math.level.mla = gender.plotly("math.level", "Math Course Level")
gender.math.level.mla
gender.race.mla = gender.plotly("race", "Race")
gender.race.mla
gender.class.mla = gender.plotly("class", "Class")
gender.class.mla
gender.major.mla = gender.plotly("major", "Major")
gender.major.mla
gender.modality.mla = gender.plotly("modality", "Modality")
gender.modality.mla

8.4 The Gender Gap in Evaluation and Learning Anxiety

It turns out that, comparing to math learning anxiety, evaluation anxiety manifests the gender gap. This observation is supported by academic research. The key insight is that the gender gap in math performance is more strongly linked to the anxiety generated by the testing situation than by anxiety toward the subject matter itself (leading potential learning anxiety).

A robust body of evidence, from foundational meta-analyses (Hembree, 1990) to contemporary studies (Devine et al., 2012; Goetz et al., 2013), establishes that female students experience disproportionately high levels of math test anxiety—a factor more predictive of academic outcomes than learning anxiety. This finding illuminates the work of Else-Quest et al. (2010), demonstrating that the gender gap in math performance is profoundly shaped by anxiety in evaluative environments. Therefore, addressing the specific pressures of testing situations is essential for closing this gap.

The following figure illustrates the relationship between gender and the two types of math anxiety: learning anxiety and evaluation anxiety.

mea0 <- final.anxiety.dat[, c("sex", "Anxiety.mea.wt.pca")]
mla0 <- final.anxiety.dat[, c("sex", "Anxiety.mla.wt.pca")]
names(mea0) = c("sex", "anxiety.score")
names(mla0) = c("sex", "anxiety.score")
mea.mla <- rbind(mea0, mla0)
anxiety.type <- c(rep("mea", dim(mea0)[1]), rep("mla", dim(mea0)[1]))
mea.mla$anxiety.type <- anxiety.type
####
df = na.omit(mea.mla)
# Create more complex grouped boxplot with statistical annotations
# Custom hover information
fig <- plot_ly(df, 
               x = ~anxiety.type, 
               y = ~anxiety.score, 
               color = ~sex,
               type = "box",
               hoverinfo = "y+x+name",
               hovertemplate = paste(
                 "Gender: %{x}<br>",
                 "Anxiety Type: %{fullData.name}<br>",
                 "Anxiety Score: %{y:.2f}<br>",
                 "<extra></extra>"
               )) %>%
  layout(
    title = "Gender Disparities in Math Evaluation and Learning Anxiety",
    xaxis = list(title = ""),
    yaxis = list(title = "Anxiety Score"),
    boxmode = "group",
    hoverlabel = list(bgcolor = "white", font = list(size = 12)),
    margin = list( t = 100,  # Adjust this value to increase or decrease the top margin
                  b = 50,
                  l = 50,
                  r = 50)
  )

fig

Our results are also consistent with existing results in literature.

9 Student Perceived Teaching Strategies and Math Anxiety

Math anxiety is often exacerbated by a disconnect between a student’s cognitive needs and the instructor’s predominant pedagogical approach. To mitigate this, a proactive method involves leveraging students’ perceptions of teaching strategies.

9.1 Heatmap of Pairwise Correlations

The following heatmap illustrates the pairwise correlations between anxiety levels, student-perceived teaching strategies, and other associated cognitive factors. A negative correlation between anxiety and another composite score (shown in blue) indicates that anxiety decreases as that composite score increases.

var.name <-c( "Anxiety.mea.wt.pca", "Anxiety.mla.wt.pca", "SelfEfficacy.wt.pca", "Technology.wt.pca",
              "Cooporative.wt.pca", "Deductive.wt.pca", "Demonstration.wt.pca",
              "Inductive.wt.pca", "Integrative.wt.pca", "LectureType.wt.pca",
              "Repetitive.wt.pca", "Engage.wt.pca", "Resource.wt.pca")
all.composite.scores <- final.anxiety.dat[, var.name]
names(all.composite.scores) <- c( "Anxiety.mea", "Anxiety.mla", "SelfEfficacy", "Technology",
              "Cooporative", "Deductive.", "Demonstration",
              "Inductive", "Integrative", "LectureType",
              "Repetitive", "Engage", "Resource.")

# Calculate correlation matrix
cor_matrix <- cor(all.composite.scores, use = "complete.obs")

# Convert to long format using melt
cor_long <- melt(cor_matrix)
names(cor_long) <- c("x", "y", "r")

# Remove self-correlations and upper triangle if desired
cor_long <- cor_long[cor_long$x != cor_long$y, ]

# Create interactive heatmap
plot_ly(cor_long, x = ~x, y = ~y, z = ~r, type = "heatmap",
        colorscale = "RdBu", zmin = -1, zmax = 1,
        hoverinfo = "text",
        text = ~paste("X:", x, "<br>Y:", y, "<br>r =", round(r, 3))) %>%
  layout(title = "Correlation Matrix",
         xaxis = list(title = ""),
         yaxis = list(title = ""),
         margin = list(l = 100, r = 50, b = 100, t = 50))

The figure above shows that all perceived teaching strategies are negatively correlated with both types of anxiety. In addition, students with high levels of self-efficacy tend to have low levels of math anxiety. Furthermore, the composite score for technology use is negatively correlated with both learning and evaluation anxiety, implying that technology can help reduce math anxiety. Conversely, we also see that students who use more learning resources tend to have higher learning anxiety.

As the red block in the center of the heatmap indicates, all teaching strategies are positively correlated. This collinearity may pose a problem for subsequent regression analysis. We will address this concern in the following section.

9.2 Grouping Teaching Strategies

The following density curves represent naive composite scores derived from the average of item scores for each of the seven teaching strategies. These curves illustrate the students’ perceptions of their instructors’ teaching strategies. A higher score indicates that students were more likely to perceive the use of that strategy.

var.name <-c( "Cooporative.avg", "Deductive.avg", "Demonstration.avg",
              "Inductive.avg", "Integrative.avg", "LectureType.avg",
              "Repetitive.avg")
all.composite.scores <- final.anxiety.dat[, var.name]
names(all.composite.scores) <- c("Cooperative", "Deductive", "Demonstrative",
              "Inductive", "Integrative", "Lecture",   "Repetitive")

# For older versions of tidyr
long_data <- all.composite.scores %>%
  pivot_longer(
    cols = c( Cooperative, Deductive, Demonstrative, Inductive, Integrative, Lecture, Repetitive),  # Columns to reshape
    names_to = "variable",          # New column name for variable names
    values_to = "value"             # New column name for values
  )

## Summarized stats

summary_stats <- long_data %>%
  group_by(variable) %>%
  summarise(
    mean_val = mean(value),
    median_val = median(value),
    sd_val = sd(value),
    n = n(),
    .groups = 'drop'
  )

# Create ridge plot with ggridges and convert to plotly
ridge_gg <- ggplot(long_data, aes(x = value, y = variable, fill = variable
  )) +
  geom_density_ridges(
    alpha = 0.7,
    scale = 2,  # Adjust overlap
    color = "white",
    size = 0.5,
     ) +
  scale_fill_brewer(palette = "Set1") +
  #theme(plot.title = element_text(hjust = 0)) +
  theme_ridges() +
  labs(
    title = "Distributions of Students' Perceived \n Teaching Strategy Indices",
    x = "Perceived Teaching Strategy Score",
    y = ""
  ) +
  theme(legend.position = "none",
        plot.title = element_text(hjust = 0.5),
        plot.margin = margin(t = 1.2, unit = "cm"))

# Convert to plotly
ggplotly(ridge_gg)

As shown in the figure, the repetitive, lecture-type, inductive, and demonstrative approaches were perceived as more popular than the integrative, deductive, and cooperative approaches. This observation aligns with the established classification of teaching styles in educational and psychological research and classic textbooks.

Teacher-centered Student-centered
Deductive (Teacher provides rules and examples: Joyce et al., 2015) Cooperative (Students work together: Johnson, 2014)
Lecture Type (Teacher transmits information: Brown,2007) Inductive (Students discover rules: Bruner, 1961; Prince & Felder, 2006)
Demonstration (Teacher shows how: Borich, 2017) Integrative (Students connect ideas: Jacobs, 1989; Fogarty,1991)
Repetitive (Teacher drills the information: Ormrod, 2020)

The above classification is consistent with the one based on cognitive demand (Bloom’s Taxonomy), which categorizes strategies as requiring either lower-level thinking (remember, understand) or higher-level thinking (apply, analyze, evaluate, create). T

This classification demonstrates a spectrum of pedagogical approaches, from traditional, highly structured methods like Lecture and Deductive teaching, to modern, student-driven methods like Inductive, Cooperative, and Integrative learning. Demonstration and Repetitive practice serve specific, often complementary, roles within this spectrum.

9.3 Create Single Composite Score for the Classification

We next define two single indices to represent the teaching strategies based on the above classification. We conceptualize teacher-centered and student-centered strategies as two single-factor constructs. The indices are defined using a doubly weighted average of the principal components. Following common practice, we report the validity and reliability measures before calculating the composite scores for the two classified teaching strategies.

Validity Measures

var.name <-c("Cooporative.cfa", "Deductive.cfa", "Demonstration.cfa",
              "Inductive.cfa", "Integrative.cfa", "LectureType.cfa",
              "Repetitive.cfa")
Stratege.wt.pca <- final.anxiety.dat[, var.name]
names(Stratege.wt.pca) <- c("Cooperative", "Deductive", "Demonstrative",
              "Inductive", "Integrative", "Lecture",   "Repetitive")



teacher0 <- Stratege.wt.pca[,c("Deductive", "Demonstrative", "Lecture", "Repetitive")]
student0 <- Stratege.wt.pca[,c("Cooperative", "Inductive", "Integrative", "Deductive")]
###
###
teacher.vlid <-cfa.analysis(teacher0)
student.vlid <-cfa.analysis(student0)
##
vlid.table <-rbind(teacher.ctrd = teacher.vlid, student.ctrd = student.vlid)
row.name <- c("teacher.ctrd", "student.ctrd")
rownames(vlid.table) <- row.name
colnames(vlid.table) <- c("std.all.min",    "pval.max", "srmr", "cfi",  "tli")
pander(vlid.table)
  std.all.min pval.max srmr cfi tli
teacher.ctrd 0.5621 0 1.269e-08 1 1
student.ctrd 0.4867 0 1.006e-09 1 1

Reliability Measures

teacher <- Stratege.wt.pca[,c("Deductive", "Demonstrative", "Lecture", "Repetitive")]
student <- Stratege.wt.pca[,c("Cooperative", "Inductive", "Integrative")]
##
teacher.reliability <- Reliability.fun(teacher)
student.reliability <- Reliability.fun(student)
##
Rel.table <-rbind(teach = anxiety.mea.rel, anxiety.mla = anxiety.mla.rel)
row.name <- c("Teacher", "Student")
col.name <- c("Cronbach alpha", "McDonald's Omega")
rownames(Rel.table) <- row.name
colnames(Rel.table) <- col.name
pander(Rel.table)
  Cronbach alpha McDonald’s Omega
Teacher 0.8413 0.846
Student 0.802 0.8052

The above goodness-of-fit and reliability measures exceed the required thresholds of validity and reliability of an instrument. The doubly weighted average of the original composite scores of teaching strategies and appended to the analytic dataset.

###################################### 
##### 
scores = function(df, dn){
  ###########################
  ## single factor score
  ##########################
  x.var <- names(df)
  n0 <- length(x.var)
  cfa.model <-  paste("latent =~", paste(x.var, collapse = " + "))
  cfa.fit <- cfa(cfa.model, data = df, estimator = "MLM")
  composite.cfa <- lavPredict(cfa.fit)
  ##########################
  # pca analysis
  ##########################
  pca.mdl <- prcomp(df, scale = TRUE)
  pca0 <- pca.mdl$x[, 1]
  r0 = cor(pca0, composite.cfa)
  if(r0 < 0) {
     pca.all <- -pca.mdl$x
  }else{
    pca.all <- pca.mdl$x
  }
  first.pca = pca.all[,1]
  ##########################
  # weighted pca score
  ##########################
  var.explained <-((pca.mdl$sdev)^2) / sum((pca.mdl$sdev)^2) #
  composite_weighted_pca <- as.matrix(pca.all) %*% (var.explained)

  outdata <- as.data.frame(cbind(pca1 = first.pca, 
                           wt.pca = as.vector(composite_weighted_pca), 
                           cfa = as.vector(composite.cfa)))
  names(outdata) <- paste0(dn,".", names(outdata), sep = "")
  outdata
 }
###
teacher <- scores(teacher, "Teacher.ctrd")
student <- scores(student, "Student.ctrd")
Anxiety.Analytic.Data <- cbind(finalDat, teacher, student)

10 Linear Regression Analysis

This section moves from the previous descriptive analyses to a regression analysis of the association between math anxiety and related factors. We examine two distinct but interconnected types of math anxiety, evaluation anxiety and learning anxiety, while temporarily setting aside their interconnection.

The regression model also incorporates the two teaching strategies as predictor variables. We also realized that the two variables are correlated.

10.1 Factors Associated with Evaluation Anxiety

For the association analysis, we will build two regression models. Both models include a common set of demographic predictors. The first model uses individual teaching strategies as additional predictors, while the second uses grouped teaching strategies.

10.1.1 Using Individual Teaching Strategies

The analysis begins with a regression model incorporating all individual teaching approaches alongside demographic and related variables as predictors.

BestSubsetsReg <- function(best.subset.model){
   # View the results
   reg.summary <- summary(best.subset.model)
 
   # Plotting the results (optional, for visualization)
   # plot(best.subset.model, scale = "adjr2", col = "skyblue") # or "bic", "cp", etc.
   par(mfrow = c(2,2))
   plot(reg.summary$rss, xlab = "Number of Variables", ylab = "RSS", type = "l", col = "navy")
   plot(reg.summary$adjr2, xlab = "Number of Variables", ylab = "Adjusted RSq", type = "l", col = "navy")
   # We will now plot a red dot to indicate the model with the largest adjusted R^2 statistic.
   # The which.max() function can be used to identify the location of the maximum point of a vector
   adj.r2.max = which.max(reg.summary$adjr2) 

   # The points() command works like the plot() command, except that it puts points 
   # on a plot that has already been created instead of creating a new plot
   points(adj.r2.max, reg.summary$adjr2[adj.r2.max], col ="darkred", cex = 2, pch = 20)
   # We'll do the same for C_p and BIC, this time looking for the models with the SMALLEST statistic
   plot(reg.summary$cp, xlab = "Number of Variables", ylab = "Cp", type = "l")
   cp.min = which.min(reg.summary$cp) # 10
   points(cp.min, reg.summary$cp[cp.min], col = "darkred", cex = 2, pch = 20)

   plot(reg.summary$bic, xlab = "Number of Variables", ylab = "BIC", type = "l")
   bic.min = which.min(reg.summary$bic) # 6
   points(bic.min, reg.summary$bic[bic.min], col = "darkred", cex = 2, pch = 20)
}
mea.lm.data <- anxiety.reg.data[,-c(2,20,21)]
mea.best.subsets.lm <- regsubsets(MEA ~., data = mea.lm.data, nvmax = 8,  method = "backward" )
BestSubsetsReg(mea.best.subsets.lm)

The above figure indicates that the 6-predictor model is the optimal choice. The results obtained from this subset selection method are identical to those obtained via stepwise variable selection.

mea.lm.data <- anxiety.reg.data[,-c(2,20,21)]
mea.lm <- lm(MEA ~SelfEfficacy + Inductive + Integrative + math.level + sex +
    Technology, data = mea.lm.data)
stepwise.mea.model <- stepAIC(mea.lm, direction = "both", trace = 0)
#summary(stepwise.mea.model)
par(mfrow = c(2,2))
plot(stepwise.mea.model )

The figure above reveals a clear pattern of non-constant residual variance (heteroscedasticity) as the fitted values increase. Because the response variable includes negative values, a standard Box-Cox transformation is not applicable for identifying a power transformation. Instead, we will use bootstrap confidence intervals for all regression coefficients to assess their significance, thereby maintaining the response variable on its original scale.

### Bootstrap confidence intervals
boot.coef <- function(data, indices) {
  d <- data[indices, ]  # resample rows
  fit <- lm(MEA ~ SelfEfficacy + Integrative + math.level + 
    sex + Technology, data = d)
  return(coef(fit))      # return coefficients
}
######
# Extract CIs for all coefficients
get.all.boot.cis <- function(boot.output, type = "perc") {
  n.coef <- ncol(boot.output$t)
  ci.matrix <- matrix(NA, nrow = n.coef, ncol = 2)
  rownames(ci.matrix) <- colnames(boot.output$t)
  colnames(ci.matrix) <- c("bt.low.95%", "bt.up.95%")
  
  for (i in 1:n.coef) {
    ci.obj <- boot.ci(boot.output, type = type, index = i)
    if (type == "perc") {
      ci.matrix[i, ] <- ci.obj$percent[4:5]
    }
  }
  
  return(ci.matrix)
}
# Perform bootstrap (R = number of resamples)
set.seed(311)  # for reproducibility
boot.results <- boot(mea.lm.data, boot.coef, R = 1000)
all.cis <- get.all.boot.cis(boot.results)
InferenceTable <- round(cbind(summary(stepwise.mea.model)$coef, all.cis),4)
print(InferenceTable) 
                 Estimate Std. Error  t value Pr(>|t|) bt.low.95% bt.up.95%
(Intercept)        0.0312     0.1056   0.2949   0.7682    -0.1878    0.2471
SelfEfficacy      -0.5769     0.0434 -13.3026   0.0000    -0.6514   -0.4940
Integrative       -0.1783     0.0379  -4.7076   0.0000    -0.2600   -0.0974
math.levelmath02   0.0782     0.1267   0.6171   0.5374    -0.1905    0.3420
math.levelmath03   0.2759     0.1344   2.0532   0.0404    -0.0007    0.5662
math.levelmath04   0.3628     0.1591   2.2801   0.0229     0.0338    0.6828
math.levelother   -0.0016     0.1607  -0.0098   0.9922    -0.3326    0.3125
math.levelstats   -0.1328     0.1279  -1.0379   0.2997    -0.4122    0.1168
sexmale           -0.3438     0.0812  -4.2369   0.0000    -0.5098   -0.1741
Technology        -0.1374     0.0251  -5.4715   0.0000    -0.1891   -0.0818

The above table revealed several significant predictors of math evaluation anxiety. Higher self-efficacy was strongly associated with lower anxiety (\(\beta = -0.577, p < 0.001\)), indicating that students who are more confident in their mathematical abilities experience less evaluation-related stress. Similarly, integrative instruction approach showed a negative relationship with anxiety (\(\beta = -0.178, p < 0.001\)), implying that this teaching method may help reduce student anxiety. Course level also played a role: students enrolled in math03 (calc A and brief Calc) (\(\beta = 0.276, p = 0.040\)) and math04 (above Calc A) (\(\beta = 0.363, p = 0.023\)) courses exhibited higher anxiety compared to the reference group, while other course levels were not significant. Gender was a significant factor, with male students reporting lower anxiety than females (\(\beta = -0.344, p < 0.001\)). Finally, technology use was negatively associated with anxiety (\(\beta = -0.137, p < 0.001\)), indicating that greater engagement with technology corresponds to reduced math evaluation anxiety.

In summary, math evaluation anxiety was significantly lower among students with higher self-efficacy. An integrative teaching approach and appropriate use of technology may help reduce math evaluation anxiety. Male students tended to experience less stress. Conversely, students enrolled in higher-level math courses (math03 and math04) reported slightly higher anxiety.

10.1.2 Using Grouped Teaching Strategies

Next, we build a regression model using the aggregated teaching styles: teacher-centered and student-centered, plus some demographic factors.

# Perform best subset selection
# 'nvmax' specifies the maximum number of variables to consider in a subset
best.subset.model.ctrd <- regsubsets(MEA~ sex+ race+ class+ major+ math.level+ modality+ SelfEfficacy+ Technology + TeacherCtrd+ StudentCtrd, data = anxiety.reg.data, nvmax = 10,  method = "backward" )
BestSubsetsReg(best.subset.model.ctrd)

coef(best.subset.model.ctrd,6)
     (Intercept)          sexmale math.levelmath03 math.levelmath04 
      0.02174423      -0.34255747       0.25944892       0.39871494 
    SelfEfficacy       Technology      StudentCtrd 
     -0.56437595      -0.13115595      -0.09586681 
# The final model
best.subset.ctrd <- lm(MEA~ sex+ math.level+  SelfEfficacy+ Technology + StudentCtrd, data = anxiety.reg.data)
#summary(best.subset.ctrd)$coef
par(mfrow = c(2,2))
plot(best.subset.ctrd)

We next perform Bootstrap regression to construct robust confidence intervals for the regression coefficients.

### Bootstrap confidence intervals
boot.coef.ctrd <- function(data, indices) {
  d <- data[indices, ]  # resample rows
  fit <- lm(MEA~ sex+ math.level+  SelfEfficacy+ Technology + StudentCtrd, data = d)
  return(coef(fit))      # return coefficients
}
# Perform bootstrap (R = number of resamples)
set.seed(312)  # for reproducibility
boot.results.ctrd <- boot(anxiety.reg.data, boot.coef.ctrd, R = 1000)
all.ctrd.cis <- get.all.boot.cis(boot.results.ctrd )
InferenceTable <- round(cbind(summary(best.subset.ctrd)$coef, all.ctrd.cis ),4)
print(InferenceTable) 
                 Estimate Std. Error  t value Pr(>|t|) bt.low.95% bt.up.95%
(Intercept)        0.0495     0.1061   0.4670   0.6406    -0.1587    0.2609
sexmale           -0.3577     0.0811  -4.4121   0.0000    -0.5221   -0.1971
math.levelmath02   0.0670     0.1271   0.5269   0.5985    -0.1929    0.3187
math.levelmath03   0.2384     0.1359   1.7552   0.0797    -0.0384    0.5184
math.levelmath04   0.3752     0.1592   2.3565   0.0187     0.0801    0.6816
math.levelother   -0.0004     0.1610  -0.0026   0.9979    -0.3420    0.3298
math.levelstats   -0.1516     0.1282  -1.1823   0.2375    -0.4356    0.1041
SelfEfficacy      -0.5591     0.0438 -12.7655   0.0000    -0.6448   -0.4744
Technology        -0.1302     0.0251  -5.1805   0.0000    -0.1845   -0.0724
StudentCtrd       -0.0950     0.0212  -4.4756   0.0000    -0.1411   -0.0515

The results above are consistent with the previous regression that used individual teaching strategies as predictors. The key difference is that the integrative teaching approach was significant in the former model, whereas student-centered teaching strategies are significant in the current one. However, since an integrative approach is a specific type of student-centered strategy, the models ultimately yield congruent findings.

10.2 Factors Associated with Learning Anxiety

Unlike math evaluation anxiety, which is fueled more by emotional and environmental factors, math learning anxiety is a direct response to the learning ecosystem. It is closely linked to the density of the learning materials, the significant cognitive load required for problem-solving, and critical external factors such as instructors’ teaching strategies.

The next regression model aims to identify factors that are directly associated with the math learning anxiety. We still take the best subset selection approach to identifying the best model.

10.2.1 Using Individual Teaching Strategies

The following model uses individual teaching strategies as predictors. This will help identify particular teaching strategies that are significantly associated with the leaning anxiety.

mla.lm.data <- anxiety.reg.data[,-c(1,20,21)]
mla.full.lm <- lm(MLA ~., data = mla.lm.data)
par(mfrow = c(2,2))
plot(mla.full.lm)

#summary(mla.full.lm)

This initial model’s residual diagnostic plot shows non-constant variance. We will not perform any power transformations on the response variable for the same reasons stated in the previous subsection. The inference on the regression coefficients will based on nonparametric Bootstrap and the classical t-tests.

We next use best subset model selection approach to identify the optimal model using various performance measures such as Cp, BIC, Adjusted coefficient of determination and the list of the significant predictors in the initial model with most of the candidate predictor variables.

mla.best.subsets.lm <- regsubsets(MLA ~., data = mla.lm.data, nvmax = 16,  method = "backward" )
BestSubsetsReg(mla.best.subsets.lm)

pred.var <- names(coef(mla.best.subsets.lm ,7))[-(1:2)]
acutal.var <-c("race", pred.var)
formula.str <- paste("MLA", "~", paste(acutal.var, collapse = " + "))
MLA.model.formula <- as.formula(formula.str)
MLA.model <- lm(MLA.model.formula , data = mla.lm.data)
summary(MLA.model )

Call:
lm(formula = MLA.model.formula, data = mla.lm.data)

Residuals:
    Min      1Q  Median      3Q     Max 
-1.8982 -0.5498 -0.1155  0.4657  2.9316 

Coefficients:
               Estimate Std. Error t value Pr(>|t|)    
(Intercept)   -0.027692   0.131309  -0.211 0.833032    
raceBlack      0.320155   0.168566   1.899 0.057946 .  
raceother      0.019621   0.167188   0.117 0.906612    
racewhite     -0.001143   0.135640  -0.008 0.993279    
SelfEfficacy  -0.398212   0.037326 -10.669  < 2e-16 ***
Technology    -0.105381   0.020638  -5.106 4.27e-07 ***
Cooporative    0.070402   0.032636   2.157 0.031340 *  
Demonstration -0.100270   0.036525  -2.745 0.006205 ** 
Lecture       -0.138858   0.038789  -3.580 0.000368 ***
Resource       0.084815   0.034172   2.482 0.013303 *  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.7837 on 685 degrees of freedom
  (1 observation deleted due to missingness)
Multiple R-squared:  0.331, Adjusted R-squared:  0.3222 
F-statistic: 37.65 on 9 and 685 DF,  p-value: < 2.2e-16
### Bootstrap confidence intervals
boot.coef.mla <- function(data, indices) {
  d <- data[indices, ]  # resample rows
  fit <- lm(MLA.model.formula, data = d)
  return(coef(fit))      # return coefficients
}
# Perform bootstrap (R = number of resamples)
set.seed(312)  # for reproducibility
boot.results.mla<- boot(mla.lm.data, boot.coef.mla, R = 1000)
all.cis.mla <- get.all.boot.cis(boot.results.mla)
InferenceTable <- round(cbind(summary(MLA.model)$coef, all.cis.mla),4)
print(InferenceTable) 
              Estimate Std. Error  t value Pr(>|t|) bt.low.95% bt.up.95%
(Intercept)    -0.0277     0.1313  -0.2109   0.8330    -0.2625    0.2342
raceBlack       0.3202     0.1686   1.8993   0.0579    -0.0362    0.6936
raceother       0.0196     0.1672   0.1174   0.9066    -0.3270    0.3451
racewhite      -0.0011     0.1356  -0.0084   0.9933    -0.2582    0.2327
SelfEfficacy   -0.3982     0.0373 -10.6686   0.0000    -0.4777   -0.3178
Technology     -0.1054     0.0206  -5.1061   0.0000    -0.1467   -0.0613
Cooporative     0.0704     0.0326   2.1572   0.0313     0.0064    0.1340
Demonstration  -0.1003     0.0365  -2.7452   0.0062    -0.1790   -0.0142
Lecture        -0.1389     0.0388  -3.5799   0.0004    -0.2199   -0.0608
Resource        0.0848     0.0342   2.4820   0.0133     0.0143    0.1552

The above results indicate that Self-Efficacy, Technology use, Demonstration, and Lecture-based teaching strategies are significant negative predictors of anxiety. Specifically, higher self-efficacy (\(\beta = -0.40, p < .001\)) and greater use of technology in learning (\(\beta = -0.11, p < .001\)) are associated with lower levels of math learning anxiety. Similarly, more frequent use of demonstrative (\(\beta = -0.10, p = .006\)) and lecture approaches (\(\beta = -0.14, p < .001\)) correspond with decreased anxiety.

Conversely, the perceived Cooperative teaching approach is positively associated with learning anxiety (\(\beta = 0.07, p = .031\)). Resource-based learning (\(\beta = 0.08, p = .013\)) is also positively associated with anxiety, suggesting that student used learning resources tended to have higher anxiety in math contexts.

The race variable approached marginal significance (p =0.058), indicating that Black students tended to have higher learning anxiety (\(\beta = 0.3202, p = .058\)).

Overall, these results highlight that students’ confidence in their math abilities and certain instructional practices play a key role in reducing math learning anxiety, while others may inadvertently increase it.

10.2.2 Using Grouped Teaching Strategies

We next build a regression similar to the above one but replace the individual teaching strategy variables with the two grouped teaching strategy variables: teacher-centered amd student-centered approaches.

mla.lm.data.ctrd <- anxiety.reg.data[,-c(1, 11:17)]
mla.full.ctrd <- lm(MLA ~., data = mla.lm.data.ctrd)
par(mfrow = c(2,2))
plot(mla.full.ctrd)

# summary(mla.full.ctrd)
mla.best.subsets.ctrd <- regsubsets(MLA ~., data = mla.lm.data.ctrd, nvmax = 16,  method = "backward" )
BestSubsetsReg(mla.best.subsets.ctrd)

pred.var.ctrd <- names(coef(mla.best.subsets.ctrd,7))[-(1:3)]
acutal.var.ctrd <-c("race", "major", pred.var.ctrd)
formula.str.ctrd <- paste("MLA", "~", paste(acutal.var.ctrd, collapse = " + "))
MLA.model.formula <- as.formula(formula.str.ctrd)
MLA.model.ctrd <- lm(MLA.model.formula , data = mla.lm.data.ctrd)
summary(MLA.model.ctrd)$coef
                 Estimate Std. Error      t value     Pr(>|t|)
(Intercept)   0.070595338 0.14573236   0.48441774 6.282450e-01
raceBlack     0.344191199 0.16932048   2.03277952 4.246166e-02
raceother     0.023582378 0.16739917   0.14087512 8.880102e-01
racewhite    -0.002697425 0.13587582  -0.01985213 9.841671e-01
majorHealth  -0.056043181 0.10931710  -0.51266619 6.083508e-01
majorOther   -0.095689044 0.08648945  -1.10636673 2.689579e-01
majorSTEM    -0.168862388 0.08156558  -2.07026516 3.880333e-02
SelfEfficacy -0.391685839 0.03747681 -10.45141749 8.125028e-24
Technology   -0.102904187 0.02124258  -4.84424072 1.574237e-06
Resource      0.088487644 0.03468369   2.55127513 1.095011e-02
TeacherCtrd  -0.181299798 0.03688029  -4.91589961 1.108172e-06
StudentCtrd   0.064877329 0.03627322   1.78857372 7.412725e-02
### Bootstrap confidence intervals
boot.coef.mla.ctrd <- function(data, indices) {
  d <- data[indices, ]  # resample rows
  fit <- lm(MLA.model.formula , data = d)
  return(coef(fit))      # return coefficients
}
# Perform bootstrap (R = number of resamples)
set.seed(312)  # for reproducibility
boot.results.ctrd <- boot(mla.lm.data.ctrd, boot.coef.mla.ctrd, R = 1000)
all.ctrd.cis <- get.all.boot.cis(boot.results.ctrd )
InferenceTable <- round(cbind(summary(MLA.model.ctrd)$coef, all.ctrd.cis ),4)
print(InferenceTable) 
             Estimate Std. Error  t value Pr(>|t|) bt.low.95% bt.up.95%
(Intercept)    0.0706     0.1457   0.4844   0.6282    -0.2034    0.3652
raceBlack      0.3442     0.1693   2.0328   0.0425    -0.0182    0.7314
raceother      0.0236     0.1674   0.1409   0.8880    -0.3316    0.3469
racewhite     -0.0027     0.1359  -0.0199   0.9842    -0.2767    0.2340
majorHealth   -0.0560     0.1093  -0.5127   0.6084    -0.2792    0.1840
majorOther    -0.0957     0.0865  -1.1064   0.2690    -0.2728    0.0825
majorSTEM     -0.1689     0.0816  -2.0703   0.0388    -0.3352   -0.0110
SelfEfficacy  -0.3917     0.0375 -10.4514   0.0000    -0.4707   -0.3130
Technology    -0.1029     0.0212  -4.8442   0.0000    -0.1462   -0.0557
Resource       0.0885     0.0347   2.5513   0.0110     0.0157    0.1610
TeacherCtrd   -0.1813     0.0369  -4.9159   0.0000    -0.2678   -0.0997
StudentCtrd    0.0649     0.0363   1.7886   0.0741    -0.0160    0.1450

The overall model was statistically significant, indicating that the set of predictors meaningfully explained variance in math learning anxiety.

Among demographic variables, race was a significant predictor. Specifically, Black students reported significantly higher anxiety than the reference Asian group (\(\beta = 0.34, p = .043\)), whereas students identifying as White or Other racial groups did not differ significantly from the reference group (\(p > .05\)). Additionally, students majoring in STEM fields reported significantly lower anxiety compared to those outside STEM majors (\(\beta = −0.17, p = .039\)). Academic majors categorized as Health or Other did not show significant relationships with anxiety (\(p > .05\)).

Psychological and instructional factors demonstrated notable associations with math learning anxiety. Higher levels of self-efficacy were strongly associated with lower anxiety (\(\beta = −0.39, p < .001\)), representing the largest effect in the model. More frequent use of technology-supported learning (\(\beta = −0.10, p < .001\)) and teacher-centered approaches (\(\beta = −0.18, p < .001\)) will help reduce anxiety levels. In contrast, increased reliance on resource-based learning strategies was positively associated with anxiety (\(\beta = 0.09, p = .011\)). Although student-centered instruction showed a positive association with anxiety, this effect did not reach statistical significance (\(\beta = 0.06, p = .074\)).

Together, these results demonstrate that confidence in one’s mathematical ability and specific instructional methods play an important role in shaping students’ math learning anxiety. Approaches that provide structured guidance—such as teacher-centered delivery and technology integration—appear to reduce anxiety, whereas greater emphasis on independent resource-based learning may contribute to increased anxiety.

11 Structural Equation Modeling Approach

Structural equation modeling (SEM) is a linear model framework that models both simultaneous regression equations with latent variables. Models such as linear regression, multivariate regression, path analysis, confirmatory factor analysis, and structural regression can be thought of as special cases of SEM. The following relationships are possible in SEM:

  • observed to observed variables (\(\gamma\), e.g., regression)
  • latent to observed variables (\(\lambda\), e.g., confirmatory factor analysis)
  • latent to latent variables (\(\gamma, \beta\), e.g., structural regression)

SEM uniquely encompasses both measurement and structural models. The measurement model relates observed to latent variables and the structural model relates latent to latent variables.

11.1 Notations and Technical Terms in SEM

Some Technical Terms in SEM:

  • observed variable: a variable that exists in the data, a.k.a item or manifest variable

  • latent variable: a variable that is constructed and does not exist in the data

  • exogenous variable: an independent variable either observed (x) or latent (\(\xi\)) that explains an endogenous variable

  • endogenous variable: a dependent variable, either observed (y) or latent (\(\eta\)) that has a causal path leading to it

  • measurement model: a model that links observed variables with latent variables

  • indicator: an observed variable in a measurement model (can be exogenous or endogenous)

  • factor: a latent variable defined by its indicators (can be exogenous or endogenous)

  • loading: a path between an indicator and a factor

  • structural model: a model that specifies causal relationships among exogenous variables to endogenous variables (can be observed or latent)

  • regression path: a path between exogenous and endogenous variables (can be observed or latent)

11.2 SEM Path Model

A path model serves as the visual and mathematical blueprint for a Structural Equation Model (SEM). This diagram employs a standardized notation to represent hypothesized relationships between variables. The specific model to be tested, which examines the complex structural relationships between endogenous and exogenous variables, has the following structure:

include_graphics("HypotheticalSEM.png")

To better understand the advantages and disadvantages of Structural Equation Modeling (SEM) for analyzing complex relationships—such as those between latent variables like math evaluation and learning anxiety. we will briefly describe its mathematical formulation and MLE of all model parameters using the above hypothetical SEM path model in the appendix.

11.3 SEM Implementation

We use the R lavaan library to implement the SEM to assess the relationship between math evaluation, learning anxiety, and related exogenous variables. The output presents results based on standardized variables. The interpretation of the regression coefficients is similar to that in a regular regression model, indicating the change in the outcome (in standard deviations) for a one-standard-deviation increase in a predictor.

Quick Reference of lavaan Syntax

  • ~ predict, used for regression of observed outcome to observed predictors (e.g., y ~ x)
  • 1=~ indicator1, used for latent variable to observed indicator in factor analysis measurement models (e.g., f =~ q + r + s)
  • `~~ covariance (e.g., x ~~ x)
  • ~1 intercept or mean (e.g., x ~ 1 estimates the mean of variable x)
  • 1* fixes parameter or loading to one (e.g., f =~ 1*q)
  • NA* frees parameter or loading (useful to override default marker method, (e.g., f =~ NA*q)
  • a* labels the parameter ‘a’, used for model constraints (e.g., f =~ a*q)
Anxiety.mea <- Comp.Anxiety[, c("AMAS.2", "AMAS.4", "AMAS.5",  "AMAS.8")]
Anxiety.mla <- Comp.Anxiety[, c("AMAS.1", "AMAS.3", "AMAS.6", "AMAS.7", "AMAS.9")]
names(Anxiety.mea) <- c("MEA2", "MEA4", "MEA5",  "MEA8")  
names(Anxiety.mla) <- c("MLA1", "MLA3", "MLA6", "MLA7", "MLA9")
factor.names <- c("Technology.wt.pca", "SelfEfficacy.wt.pca", "Engage.wt.pca", "sex",
                  "Teacher.ctrd.wt.pca", "Student.ctrd.wt.pca", "Resource.wt.pca")
##
factor.var <- Anxiety.Analytic.Data[, factor.names]
names(factor.var) <- c("Tech", "Efficacy", "Engage", "gender",
                  "Teacher.ctrd", "Student.ctrd", "Resource")

### strategies var
stratgy.var <-c("Cooporative.wt.pca", "Deductive.wt.pca", "Demonstration.wt.pca", "Inductive.wt.pca","Integrative.wt.pca" ,"LectureType.wt.pca", "Repetitive.wt.pca" )
strategy.name <- c("Coop", "Deduc", "Demon", "Induc","Integ" ,"Lect", "Repet" )
teachingstrategy <- Anxiety.Analytic.Data[, stratgy.var]
names(teachingstrategy) <- strategy.name 
SEM.data <- cbind(Anxiety.mea, Anxiety.mla, factor.var,teachingstrategy )

###  SEM models

SEMModel <-
' Eval.Anxiety =~  MEA2 + MEA4 + MEA5 + MEA8  ## measurement model for Eval.Anxiety
  Learn.Anxiety =~ MLA1 + MLA3 + MLA6 + MLA7 + MLA9   ## measurement model for Learn.Anxiety 
  TeacherCtrd =~ Deduc + Lect + Demon + Repet  # Teacher centered
  StudentCtrd =~ Coop + Induc + Integ  # Student centered
  Eval.Anxiety ~ Tech + Efficacy + Engage + gender + TeacherCtrd + StudentCtrd + Resource    ## Eval.Anxiety as an outcome
  Learn.Anxiety ~ Tech + Efficacy + Engage + gender + TeacherCtrd+ StudentCtrd + Resource    ## Learn.Anxiety as an outcome
  Eval.Anxiety ~~ Learn.Anxiety     ## correlation between Eval.Anxiety and Learn.Anxiety 
'
 
output <- sem(model = SEMModel, data = SEM.data, std.lv = TRUE,
              missing = "fiml", mimic = "Mplus")
results <- summary(output, standardized = TRUE, fit.measures = TRUE)

The component regression ans latent models in the SEM are specified in the following.

  ## measurement model for Eval.Anxiety
  Eval.Anxiety =~  MEA2 + MEA4 + MEA5 + MEA8            
  ## measurement model for Learn.Anxiety 
  Learn.Anxiety =~ MLA1 + MLA3 + MLA6 + MLA7 + MLA9  
  # Latent regression of teaching Strategies
  TeacherCtrd =~ Deduc + Lect + Demon + Repet  # Teacher centered
  StudentCtrd =~ Coop + Induc + Integ  # Student centered
  ## Eval.Anxiety as an outcome
  Eval.Anxiety ~ Tech + Efficacy + Engage + gender + Teacher.ctrd + Student.ctrd + Resource + race   
  ## Learn.Anxiety as an outcome
  Learn.Anxiety ~ Tech + Efficacy + Engage + gender + Teacher.ctrd + Student.ctrd + Resource + race  
  Eval.Anxiety ~~ Learn.Anxiety     ## correlation between Eval.Anxiety and Learn.Anxiety 

The key goodness-of-fit statistics and estimated parameters are summarized in the following.

interpret_fit <- function(fit_obj) {
  measures <- fitMeasures(fit_obj)
  
  #cat("=== SEM MODEL FIT ASSESSMENT ===\n")
  cat(sprintf("Chi-Square: χ²(%d) = %.2f, p = %.3f\n", 
              measures["df"], measures["chisq"], measures["pvalue"]))
  cat(sprintf("CFI: %.3f %s\n", measures["cfi"],
              ifelse(measures["cfi"] >= 0.95, "(Excellent)",
                     ifelse(measures["cfi"] >= 0.90, "(Acceptable)", "(Poor)"))))
  cat(sprintf("TLI: %.3f %s\n", measures["tli"],
              ifelse(measures["tli"] >= 0.95, "(Excellent)",
                     ifelse(measures["tli"] >= 0.90, "(Acceptable)", "(Poor)"))))
  cat(sprintf("RMSEA: %.3f [90%% CI: %.3f, %.3f] %s\n", 
              measures["rmsea"], measures["rmsea.ci.lower"], measures["rmsea.ci.upper"],
              ifelse(measures["rmsea"] <= 0.06, "(Excellent)",
                     ifelse(measures["rmsea"] <= 0.08, "(Acceptable)", "(Poor)"))))
  cat(sprintf("SRMR: %.3f %s\n", measures["srmr"],
              ifelse(measures["srmr"] <= 0.08, "(Excellent)",
                     ifelse(measures["srmr"] <= 0.10, "(Acceptable)", "(Poor)"))))
}

###
report_sem <- function(fit, model_name = "The SEM") {
  
  # Fit measures
  fit_meas <- fitMeasures(fit, c("chisq", "df", "pvalue", "cfi", "tli", 
                                "rmsea", "rmsea.ci.lower", "rmsea.ci.upper", "srmr"))
  
  # Parameters
  params <- parameterEstimates(fit)
  std_params <- standardizedSolution(fit)
  
  cat("=== STRUCTURAL EQUATION MODELING RESULTS ===\n\n")
  cat("MODEL FIT:\n")
  
  # Use the function
  interpret_fit(output)
  cat("\n\n")
  # Significant structural paths
  sig_paths <- std_params[std_params$op == "~" & std_params$pvalue < 0.1, ]
  if (nrow(sig_paths) > 0) {
    cat("SIGNIFICANT STRUCTURAL PATHS:\n")
    for (i in 1:nrow(sig_paths)) {
      cat(sprintf("- %s → %s: β = %.2f, p = %.3f\n",
                  sig_paths$rhs[i], sig_paths$lhs[i],
                  sig_paths$est[i], sig_paths$pvalue[i]))
    }
    cat("\n")
  }
  
  # factor loading for latent variables
  cat("\n\nFACTOR LOADINGS\n\n")
  
  print(std_params[std_params$op == "=~", ])
  
  #####
  # R-squared
  r2 <- inspect(fit, "r2")
  if (length(r2) > 0) {
    cat("VARIANCE EXPLAINED (R²):\n\n")
    for (i in 1:length(r2)) {
      cat(sprintf("- %s: %.1f%%\n", names(r2)[i], r2[i] * 100))
    }
  }
  
  ## Regression coefficients
  
  cat("\n\nCOEFFICIENTS OF REGRESSION\n\n")
  
  print(std_params[std_params$op == "~", ])
  
     # Covariance between Math Anxieties
      #param_est <- parameterEstimates(fit)
     cov_latent <- std_params[
              std_params$lhs == "MathEval" & 
              std_params$rhs == "LearnAnx" & 
              std_params$op == "~~",
          ]
     ###
     cat("\n\nCOVARIANCE :\n")
     latent_cov_matrix <- lavInspect(fit, "est")$psi
     cov_out <- latent_cov_matrix["Learn.Anxiety", "Eval.Anxiety"]
     cat("- Learn.Anxiety and Eval.Anxiety:", cov_out)
}

# Use the function
report_sem(output, "Math Anxiety")
=== STRUCTURAL EQUATION MODELING RESULTS ===

MODEL FIT:
Chi-Square: χ²(168) = 664.84, p = 0.000
CFI: 0.928 (Acceptable)
TLI: 0.914 (Acceptable)
RMSEA: 0.065 [90% CI: 0.060, 0.070] (Acceptable)
SRMR: 0.069 (Excellent)


SIGNIFICANT STRUCTURAL PATHS:
- Tech → Eval.Anxiety: β = -0.13, p = 0.000
- Efficacy → Eval.Anxiety: β = -0.47, p = 0.000
- gender → Eval.Anxiety: β = -0.13, p = 0.000
- Tech → Learn.Anxiety: β = -0.20, p = 0.000
- Efficacy → Learn.Anxiety: β = -0.42, p = 0.000
- StudentCtrd → Learn.Anxiety: β = -0.53, p = 0.046
- Resource → Learn.Anxiety: β = 0.12, p = 0.001



FACTOR LOADINGS

             lhs op   rhs est.std    se      z pvalue ci.lower ci.upper
1   Eval.Anxiety =~  MEA2   0.886 0.012 71.001      0    0.862    0.911
2   Eval.Anxiety =~  MEA4   0.861 0.013 64.518      0    0.835    0.887
3   Eval.Anxiety =~  MEA5   0.600 0.026 22.901      0    0.549    0.651
4   Eval.Anxiety =~  MEA8   0.640 0.024 26.316      0    0.592    0.688
5  Learn.Anxiety =~  MLA1   0.510 0.031 16.607      0    0.450    0.570
6  Learn.Anxiety =~  MLA3   0.716 0.022 31.975      0    0.672    0.760
7  Learn.Anxiety =~  MLA6   0.701 0.023 30.238      0    0.656    0.747
8  Learn.Anxiety =~  MLA7   0.644 0.026 25.173      0    0.594    0.694
9  Learn.Anxiety =~  MLA9   0.723 0.022 32.396      0    0.680    0.767
10   TeacherCtrd =~ Deduc   0.887 0.010 93.255      0    0.869    0.906
11   TeacherCtrd =~  Lect   0.866 0.011 79.059      0    0.845    0.888
12   TeacherCtrd =~ Demon   0.806 0.015 55.122      0    0.778    0.835
13   TeacherCtrd =~ Repet   0.760 0.017 44.077      0    0.726    0.793
14   StudentCtrd =~  Coop   0.735 0.018 39.927      0    0.699    0.771
15   StudentCtrd =~ Induc   0.861 0.012 73.779      0    0.838    0.884
16   StudentCtrd =~ Integ   0.673 0.022 30.501      0    0.630    0.717
VARIANCE EXPLAINED (R²):

- MEA2: 78.5%
- MEA4: 74.2%
- MEA5: 36.0%
- MEA8: 41.0%
- MLA1: 26.0%
- MLA3: 51.3%
- MLA6: 49.2%
- MLA7: 41.5%
- MLA9: 52.3%
- Deduc: 78.7%
- Lect: 75.0%
- Demon: 65.0%
- Repet: 57.7%
- Coop: 54.0%
- Induc: 74.2%
- Integ: 45.4%
- Eval.Anxiety: 34.5%
- Learn.Anxiety: 33.0%


COEFFICIENTS OF REGRESSION

             lhs op         rhs est.std    se       z pvalue ci.lower ci.upper
17  Eval.Anxiety  ~        Tech  -0.129 0.036  -3.615  0.000   -0.198   -0.059
18  Eval.Anxiety  ~    Efficacy  -0.471 0.032 -14.687  0.000   -0.534   -0.408
19  Eval.Anxiety  ~      Engage  -0.006 0.036  -0.166  0.868   -0.077    0.065
20  Eval.Anxiety  ~      gender  -0.130 0.035  -3.717  0.000   -0.199   -0.061
21  Eval.Anxiety  ~ TeacherCtrd  -0.115 0.225  -0.512  0.609   -0.555    0.325
22  Eval.Anxiety  ~ StudentCtrd  -0.066 0.222  -0.298  0.766   -0.501    0.369
23  Eval.Anxiety  ~    Resource  -0.003 0.035  -0.084  0.933   -0.072    0.066
24 Learn.Anxiety  ~        Tech  -0.202 0.038  -5.375  0.000   -0.276   -0.128
25 Learn.Anxiety  ~    Efficacy  -0.416 0.036 -11.646  0.000   -0.486   -0.346
26 Learn.Anxiety  ~      Engage  -0.047 0.039  -1.217  0.224   -0.123    0.029
27 Learn.Anxiety  ~      gender   0.027 0.038   0.728  0.467   -0.046    0.101
28 Learn.Anxiety  ~ TeacherCtrd   0.288 0.267   1.078  0.281   -0.236    0.813
29 Learn.Anxiety  ~ StudentCtrd  -0.529 0.265  -1.994  0.046   -1.050   -0.009
30 Learn.Anxiety  ~    Resource   0.124 0.037   3.325  0.001    0.051    0.197


COVARIANCE :
- Learn.Anxiety and Eval.Anxiety: 0.5288637

The regression coefficients and factor loadings in the above table are summarized in the following SEM path diagram generated using lavaanPlot function.

lavaanPlot(model = output,
           coefs = TRUE,
           stand = TRUE,
           stars = c("regress"))  # Add significance stars

The path diagram generated by R for the SEM analysis is not easy to read. Therefore, we sketched a new path diagram that includes only the significant regression coefficients and factor loadings.

include_graphics("FittedlSEM.png")

11.4 Results and Discussion of SEM Anlysis

11.4.1 Results

The hypothesized structural equation model demonstrated an acceptable fit to the data: \(\chi^2(168) = 664.75, p < .001\); \(CFI = 0.927; TLI = 0.913\); \(RMSEA = 0.065 (90% CI [0.060, 0.070])\); and \(SRMR = 0.070\) These fit indices indicate that the proposed model adequately represents the observed data, with values meeting or exceeding conventional thresholds for acceptable model fit.

Several significant structural paths emerged. Technology use was a significant negative predictor of both evaluation anxiety (\(\beta = –0.13, p < .001\)) and learning anxiety (\(\beta = –0.20, p < .001\)), suggesting that greater technological proficiency or integration was associated with reduced anxiety in both contexts. Similarly, self-efficacy negatively predicted evaluation anxiety (\(\beta = –0.47, p < .001\)) and learning anxiety (\(\beta = –0.42, p < .001\)), indicating that individuals with higher self-efficacy experienced lower levels of anxiety.

Gender also had a significant effect on evaluation anxiety (\(\beta = –0.13, p < .001\)), implying potential gender-based differences in evaluation-related apprehension. Although student-centered instruction was marginally related to learning anxiety (\(\beta = –0.51, p = .059\)), resource availability positively predicted learning anxiety (\(\beta = 0.12, p = .001\)), indicating that access to additional resources may not uniformly alleviate anxiety and could, in some contexts, contribute to increased pressure or cognitive load. Other hypothesized paths (e.g., engagement, teacher-centered approaches) were not statistically significant (all \(p > .05\)).

All observed indicators loaded significantly onto their respective latent constructs (all \(p < .001\)), with standardized factor loadings ranging from 0.51 to 0.88, supporting construct validity. For Evaluation Anxiety, the strongest indicators were MEA2 (\(\lambda = 0.883\)) and MEA4 (\(\lambda = 0.857\)). For Learning Anxiety, the highest loadings were observed for MLA9 (\(\lambda = 0.725\)) and MLA3 (\(\lambda = 0.714\)). Among teaching approaches, Teacher-Centered Instruction was best represented by Deductive (\(\lambda = 0.886\)) and Lecture (\(\lambda = 0.868\)) methods, while Student-Centered Instruction was best reflected by Inductive (\(\lambda = 0.862\)) and Cooperative (\(\lambda = 0.733\)) strategies.

The model accounted for 34.9% of the variance in evaluation anxiety and 33.4% of the variance in learning anxiety, indicating moderate explanatory power. The covariance between evaluation anxiety and learning anxiety was significant and positive (\(r = 0.53\)), suggesting that while distinct, these two forms of anxiety are moderately correlated.

Overall, the results highlight the pivotal role of self-efficacy and technology use in mitigating both evaluation and learning-related anxiety. These findings align with prior research emphasizing that confidence in one’s abilities and familiarity with digital tools can enhance perceived control and reduce anxiety in academic contexts. The marginal influence of student-centered approaches suggests potential benefits for reducing learning anxiety through active and participatory learning environments, although the effect did not reach conventional significance. The positive association between resource availability and anxiety may indicate that while access to materials supports learning, it can also introduce information overload or performance expectations that heighten anxiety. Together, these findings underscore the multifaceted nature of academic anxiety and point to the importance of fostering efficacy and technological readiness to create supportive learning environments.

These findings collectively inform the subsequent discussion on how instructional design, self-efficacy, and technology integration interact to influence learners’ emotional experiences and academic engagement.

11.4.2 Discussion

The present study investigated the structural relationships among technology use, self-efficacy, instructional approaches, and two forms of academic anxiety—evaluation anxiety and learning anxiety—within a comprehensive structural equation modeling (SEM) framework. The findings provide important insights into how individual and instructional factors jointly shape learners’ emotional experiences in academic contexts.

Consistent with prior research, self-efficacy emerged as the most robust predictor of both evaluation and learning anxiety. Students who reported higher confidence in their academic abilities experienced significantly lower levels of anxiety, underscoring the protective function of self-belief in coping with academic demands. Similarly, technology use negatively predicted both types of anxiety, suggesting that familiarity and comfort with technological tools may help students navigate learning environments more effectively and reduce apprehension about performance.

Although student-centered instruction was only marginally associated with reduced learning anxiety, the direction of this relationship is theoretically meaningful. Learners exposed to inductive, cooperative, and integrative teaching strategies may perceive greater autonomy and support, which can lessen anxiety and foster intrinsic motivation. The positive association between resource availability and learning anxiety suggests that access to abundant materials does not necessarily alleviate stress; instead, it may introduce cognitive overload or performance pressure.

Gender significantly predicted evaluation anxiety, highlighting the importance of considering sociocultural and disciplinary factors that shape how gender interacts with academic emotions. The strong positive covariance between evaluation and learning anxiety indicates that these constructs are related yet distinct, supporting theories that emphasize interconnected emotional experiences in learning.

The findings underscore the need for instructional designs that enhance self-efficacy and technological confidence as central strategies for reducing academic anxiety. Instructors can promote self-efficacy through scaffolded feedback, mastery-oriented assessments, and opportunities for self-reflection. Purposeful technology integration and structured guidance can further support confidence and reduce anxiety. Future studies should explore additional predictors and contextual variables, as well as employ longitudinal designs to clarify causal pathways.

In summary, the findings demonstrate that self-efficacy and technology use are key protective factors against both evaluation and learning anxiety, whereas instructional context and resource management play secondary roles. These insights contribute to a growing understanding of how personal and pedagogical factors interact to shape emotional experiences in learning environments.

11.4.3 Practical Implications

  1. Enhance Students’ Self-Efficacy: Provide opportunities for early success, mastery experiences, and positive feedback to build learners’ confidence.
  2. Promote Meaningful Technology Integration: Integrate digital tools purposefully within instruction to foster engagement and reduce technology-related anxiety.
  3. Adopt Student-Centered Teaching Practices: Encourage collaborative, problem-based, and peer-driven learning to alleviate anxiety and promote autonomy.
  4. Balance Resource Provision and Cognitive Load: Curate instructional materials carefully to prevent information overload and ensure clarity of expectations.
  5. Address Gender and Contextual Differences: Tailor support strategies to address potential gender-based and contextual variations in academic anxiety.

11.4.4 Summary of Key Findings

This study employed structural equation modeling to examine the interplay among technology use, self-efficacy, instructional approaches, and two dimensions of academic anxiety: evaluation anxiety and learning anxiety. The model demonstrated an acceptable overall fit and explained a substantial proportion of variance in both outcomes.

The results revealed that self-efficacy and technology use were the strongest protective factors against academic anxiety. Self-efficacy had the largest negative associations with both evaluation and learning anxiety, indicating that students who feel competent are less likely to experience anxiety across academic contexts. Technology use similarly reduced anxiety, suggesting that familiarity with digital tools fosters comfort and perceived control during learning and assessment.

While student-centered instruction showed a marginally negative relationship with learning anxiety, resource availability unexpectedly predicted higher anxiety. Gender differences also emerged for evaluation anxiety, suggesting variation in emotional responses to academic evaluation across groups.

Together, these findings demonstrate that fostering self-efficacy, digital competence, and balanced instructional design can substantially reduce students’ anxiety and promote more positive academic experiences. The study contributes to a growing body of evidence highlighting the interconnected roles of personal beliefs, technology, and pedagogy in shaping students’ emotional engagement and success.


12 References

Borich, G. D. (2017). Effective Teaching Methods: Research-Based Practice (9th ed.). Pearson. Brown, H. D., & Lee, H. (1994). Teaching by principles: An interactive approach to language pedagogy (Vol. 1, p. 994). Englewood Cliffs, NJ: Prentice Hall Regents.

Bruner, J. S. (1961). The act of discovery. Harvard educational review. Cattell, R. B. (1952). Factor analysis: an introduction and manual for the psychologist and social scientist.

Chang, H., & Beilock, S. L. (2016). The math anxiety-math performance link and its relation to individual and environmental factors: A review of current behavioral and psychophysiological research. Current Opinion in Behavioral Sciences, 10, 33–38.

Cronbach, L. J. (1951). Coefficient alpha and the internal structure of tests. Biometrika, 16, 297–335.

Daker, R. J., Gattas, S. U., Sokolowski, H. M., Green, A. E., & Lyons, I. M. (2021). First-year students’ math anxiety predicts STEM avoidance and underperformance throughout university, independently of math ability. Npj Science of Learning, 6(1), 17.

Devine, A., Fawcett, K., Szűcs, D., & Dowker, A. (2012). Gender differences in mathematics anxiety and the relation to mathematics performance while controlling for test anxiety. Behavioral and brain functions, 8(1), 33.

DiStefano, C., Zhu, M., & Mindrila, D. (2009). Understanding and using factor scores: Considerations for the applied researcher. Practical assessment, research, and evaluation, 14(1).

Dreger, R. M., & Aiken Jr, L. R. (1957). The identification of number anxiety in a college population. Journal of Educational Psychology, 48(6), 344.

Duncan, O. D. (1961). A socioeconomic index for all occupations. Occupations and social status..

Else-Quest, N. M., Hyde, J. S., & Linn, M. C. (2010). Cross-national patterns of gender differences in mathematics: a meta-analysis. Psychological bulletin, 136(1), 103.

Fogarty, R. (1991). The mindful school: How to integrate the curricula. Palatine, IL. SkyLight Publishing, Inc. Retrieved February, 22, 2002.

Goetz, T., Bieg, M., Lüdtke, O., Pekrun, R., & Hall, N. C. (2013). Do girls really experience more anxiety in mathematics?. Psychological science, 24(10), 2079-2087.

Gough, Mary O. (1954). Why failures in mathematics? Mathemaphobia: Causes and treatments. The Clearing House: A Journal of Educational Strategies, Issues and Ideas, 28(5), 290–294.

Guttman, L. (1954). Some necessary conditions for common-factor analysis. Psychometrika, 19(2), 149-161.

Hembree, R. (1990). The nature, effects, and relief of mathematics anxiety. Journal for research in mathematics education, 21(1), 33-46.

Hopko, D. R., Mahadevan, R., Bare, R. L., & Hunt, M. K. (2003). The abbreviated math anxiety scale (AMAS) construction, validity, and reliability. Assessment, 10(2), 178–182.

Hirschberg, E., & Standish, C. V. (1959). A method of deriving a stratification score by using the principal components of the correlation matrix. American Statistical Association, Proceedings of the Social Statistics Section, 1959, 220-225.

Jacobs, H. H. (1989). Interdisciplinary curriculum: Design and implementation. Association for Supervision and Curriculum Development, 1250 N. Pitt Street, Alexandria, VA 22314.

Jolliffe, I. T., & Cadima, J. (2016). Principal Component Analysis: A Review and Recent Developments. Philosophical Transactions of the Royal Society A, 374(2065), 20150202.

Johnson, D. W., Johnson, R. T., & Smith, K. A. (2014). Cooperative learning: Improving university instruction by basing practice on validated theory. Journal on excellence in college teaching, 25(3&4).

Jose M. Cardino Jr. and Ruth A. Ortega-Dela Cruz, Understanding of learning styles and teaching strategies towards improving the teaching and learning of mathematics, LUMAT General Issue, Vol 8 No 1 (2020), 19–43. Doi: 10.31129/ LUMAT.8.1.1348

Joyce, B., Weil, M., & Calhoun, E. (2015). Models of Teaching (9th ed.). Pearson.

Klee, H. L., Buehl, M. M., & Miller, A. D. (2022). Strategies for alleviating students’ math anxiety: Control-value theory in practice. Theory Into Practice, 61(1), 49–61.

Lazarsfeld, P. F., Stouffer, S. A., Guttman, L., & Suchman, E. A. (1950). Measurement and prediction. SA Stouffer (éd.) Studies in social psychology in world war II, 4.

López-Bonilla, J. M.l and López-Bonilla, L. M. (2012), Validation of an information technology anxiety scale in undergraduates, British Journal of Educational Technology Vol 43. No 2. E56–E58. doi:10.1111/j.1467-8535.2011.01256.x

Marsh, H. W. (1996). Positive and negative self-esteem: A substantively meaningful distinction or artifactors? Journal of Personality and Social Psychology, 70(4), 810–819.

McDonald, R. P. (1999). Test theory: A unified treatment. Mahwah: Erlbaum.

Moliner, L., & Alegre, F. (2020). Peer tutoring effects on students’ mathematics anxiety: A middle school experience. Frontiers in Psychology, 11, 1610.

O’Leary, K., Fitzpatrick, C. L., & Hallett, D. (2017). Math anxiety is related to some, but not all, experiences with math. Frontiers in Psychology, 8, 2067.

Ormrod, J. E. (2020). Human Learning (8th ed.). Pearson

Pletzer, B., Wood, G., Scherndl, T., Kerschbaum, H. H., & Nuerk, H.C. (2016). Components of mathematics anxiety: Factor modeling of the MARS30-brief. Frontiers in Psychology, 7, 91.

Prince, M. J., & Felder, R. M. (2006). Inductive teaching and learning methods: Definitions, comparisons, and research bases. Journal of engineering education, 95(2), 123-138.

Richardson, F. C., & Suinn, R. M. (1972). The mathematics anxiety rating scale: Psychometric data. Journal of Counseling Psychology, 19(6), 551.

Rozgonjuk, D., Kraav, T., Mikkor, K., Orav-Puurand, K., & Täht, K. (2020). Mathematics anxiety among STEM and social science students: The roles of mathematics self-efficacy, and deep and surface approach to learning. International Journal of STEM Education, 7(1), 1–11.

Segool, N. K., Carlson, J. S., Goforth, A. N., Von Der Embse, N., & Barterian, J. A. (2013). Heightened test anxiety among young children: Elementary school students’ anxious responses to high-stakes testing. Psychology in the Schools, 50(5), 489–499.

Watson, D., Clark, L. A., & Tellegen, A. (1988). Development and validation of brief measures of positive and negative affect: The PANAS scales. Journal of Personality and Social Psychology, 54(6), 1063–1070.

Wilson, S. (2013). Mature age pre-service teachers’ mathematics anxiety and factors impacting on university retention. Mathematics Education: Yesterday, Today and Tomorrow (MERGA36), 666–673.


13 Appendices

13.1 Mathematics of PCA

1. Problem Definition

We will use a questionnaire with four items that assess math evaluation anxiety to demonstrate the procedure.

  • \(x_1\): Thinking about a math test the day before you take it.
  • \(x_2\): Taking a math test.
  • \(x_3\): Being given a homework assignment of many difficult problems that is due for the next class meeting.
  • \(x_4\): Being given a quiz on math without knowing in advance.

Let \(\mathbf{x} = [x_1, x_2, x_3, x_4]^T\) be a random vector representing the responses of a randomly selected individual to the four items. We assume \(\mathbf{x}\) has a population mean vector \(\boldsymbol{\mu}\) and population covariance matrix \(\boldsymbol{\Sigma}\).

We collect a sample of \(n\) individuals. The data matrix is \(\mathbf{X}_{n \times 4}\), where each row is an individual’s response vector. The sample mean vector is \(\bar{\mathbf{x}}\), and the sample covariance matrix is \(\mathbf{S}\).

2. Preprocessing: Centering the Data

The first step is to center the data. We subtract the mean of each variable, creating a new data matrix \(\mathbf{Y}\):

\[ \mathbf{Y} = \mathbf{X} - \mathbf{1}\bar{\mathbf{x}}^T \]

where \(\mathbf{1}\) is an \(n \times 1\) vector of ones. The elements of \(\mathbf{Y}\) are \(y_{ij} = x_{ij} - \bar{x}_j\). From this point forward, we work with the centered data \(\mathbf{Y}\), ensuring \(E[\mathbf{y}] = \mathbf{0}\).

3. Goal of Principal Component Analysis (PCA)

The goal of PCA is to find a new set of uncorrelated variables \(\mathbf{z} = [z_1, z_2, z_3, z_4]^T\), called the (PCs), which are linear combinations of the original centered variables \(\mathbf{y}\).

\[ \mathbf{z} = \mathbf{W}^T\mathbf{y} \]

The matrix \(\mathbf{W}\) is an orthogonal matrix (\(\mathbf{W}^T\mathbf{W} = \mathbf{I}\)) whose columns \(\mathbf{w}_i\) are the . The components must satisfy:

  • The first component, \(z_1 = \mathbf{w}_1^T \mathbf{y}\), has the maximum possible variance.
  • The \(k\)-th component, \(z_k = \mathbf{w}_k^T \mathbf{y}\), has the maximum possible variance subject to being uncorrelated with (orthogonal to) all previous components \(z_1, \dots, z_{k-1}\).

4. Derivation of the First Principal Component

Let \(\mathbf{w}_1\) be the vector of weights for the first PC, \(z_1 = \mathbf{w}_1^T \mathbf{y}\). The sample variance of \(z_1\) is given by:

\[ \begin{align*} \text{Var}(z_1) &= \text{Var}(\mathbf{w}_1^T \mathbf{y}) \\ &= E[(\mathbf{w}_1^T \mathbf{y})(\mathbf{w}_1^T \mathbf{y})^T] \quad \text{(since} E[\mathbf{y}]=\mathbf{0}) \\ &= E[\mathbf{w}_1^T \mathbf{y} \mathbf{y}^T \mathbf{w}_1] \\ &= \mathbf{w}_1^T E[\mathbf{y} \mathbf{y}^T] \mathbf{w}_1 \\ &= \mathbf{w}_1^T \boldsymbol{\Sigma} \mathbf{w}_1 \end{align*} \]

In practice, we use the sample covariance matrix \(\mathbf{S} = \frac{1}{n-1} \mathbf{Y}^T \mathbf{Y}\).

We wish to maximize \(\mathbf{w}_1^T \mathbf{S} \mathbf{w}_1\) subject to the normalization constraint \(\mathbf{w}_1^T \mathbf{w}_1 = 1\) (to prevent the variance from growing arbitrarily large). We solve this using the method of Lagrange multipliers.

The Lagrangian is:

\[ \mathcal{L}(\mathbf{w}_1, \lambda_1) = \mathbf{w}_1^T \mathbf{S} \mathbf{w}_1 - \lambda_1 (\mathbf{w}_1^T \mathbf{w}_1 - 1) \]

Taking the gradient with respect to \(\mathbf{w}_1\) and setting it to zero:

\[ \frac{\partial \mathcal{L}}{\partial \mathbf{w}_1} = 2\mathbf{S}\mathbf{w}_1 - 2\lambda_1 \mathbf{w}_1 = 0 \]

This yields the key :

\[ \begin{equation} \mathbf{S} \mathbf{w}_1 = \lambda_1 \mathbf{w}_1 \end{equation} \]

Substituting the above equation back into the variance expression:

\[ \text{Var}(z_1) = \mathbf{w}_1^T \mathbf{S} \mathbf{w}_1 = \mathbf{w}_1^T (\lambda_1 \mathbf{w}_1) = \lambda_1 \mathbf{w}_1^T \mathbf{w}_1 = \lambda_1 \]

Thus, the variance of the first principal component \(z_1\) is the eigenvalue \(\lambda_1\). To maximize the variance, we must choose the .

5. Derivation of the Second Principal Component

We now seek the second component \(z_2 = \mathbf{w}_2^T \mathbf{y}\) that has maximum variance, subject to \(\mathbf{w}_2^T \mathbf{w}_2 = 1\) and \(\mathbf{w}_2^T \mathbf{w}_1 = 0\) (ensuring \(z_2\) is uncorrelated with \(z_1\)).

The Lagrangian for this problem is:

\[ \mathcal{L}(\mathbf{w}_2, \lambda_2, \phi) = \mathbf{w}_2^T \mathbf{S} \mathbf{w}_2 - \lambda_2 (\mathbf{w}_2^T \mathbf{w}_2 - 1) - \phi (\mathbf{w}_2^T \mathbf{w}_1) \]

Taking the gradient with respect to \(\mathbf{w}_2\) and setting it to zero:

\[ \frac{\partial \mathcal{L}}{\partial \mathbf{w}_2} = 2\mathbf{S}\mathbf{w}_2 - 2\lambda_2 \mathbf{w}_2 - \phi \mathbf{w}_1 = 0 \]

Multiply this equation on the left by \(\mathbf{w}_1^T\):

\[ 2\mathbf{w}_1^T\mathbf{S}\mathbf{w}_2 - 2\lambda_2 \mathbf{w}_1^T\mathbf{w}_2 - \phi \mathbf{w}_1^T\mathbf{w}_1 = 0 \]

From the eigenvalue equation for \(\mathbf{w}_1\), we know \(\mathbf{w}_1^T\mathbf{S} = \lambda_1 \mathbf{w}_1^T\). The orthogonality constraint gives \(\mathbf{w}_1^T\mathbf{w}_2=0\). Substituting these:

\[ 2\lambda_1 \mathbf{w}_1^T\mathbf{w}_2 - 0 - \phi (1) = 0 \implies 2\lambda_1 (0) - \phi = 0 \implies \phi = 0 \]

With \(\phi=0\), the gradient equation simplifies to:

\[ 2\mathbf{S}\mathbf{w}_2 - 2\lambda_2 \mathbf{w}_2 = 0 \implies \mathbf{S} \mathbf{w}_2 = \lambda_2 \mathbf{w}_2 \]

This is again an eigenvalue equation. The variance of \(z_2\) is \(\lambda_2\). To maximize the variance, we choose the eigenvector \(\mathbf{w}_2\) corresponding to the \(\lambda_2\). The orthogonality \(\mathbf{w}_2^T \mathbf{w}_1 = 0\) is automatically satisfied for distinct eigenvalues since \(\mathbf{S}\) is symmetric.

6. Subsequent Components and Full Solution

This process continues for all four components. The solution to the PCA problem is found by performing the of the sample covariance matrix \(\mathbf{S}\):

\[ \mathbf{S} = \mathbf{W} \boldsymbol{\Lambda} \mathbf{W}^T \]

where:

  • \(\boldsymbol{\Lambda}\) is a diagonal matrix containing the eigenvalues in descending order: \(\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge \lambda_4 \ge 0\).
  • \(\mathbf{W} = [\mathbf{w}_1, \mathbf{w}_2, \mathbf{w}_3, \mathbf{w}_4]\) is an orthogonal matrix whose columns are the corresponding eigenvectors.

The principal components for an individual with centered response vector \(\mathbf{y}\) are then computed as:

\[ \mathbf{z} = \mathbf{W}^T \mathbf{y} \]

The \(k\)-th PC score is \(z_k = \mathbf{w}_k^T \mathbf{y}\).

7. Variance Explained

The total variance in the original data is the sum of the variances of the centered variables, which is the trace of \(\mathbf{S}\).

\[ \text{Total Variance} = \text{tr}(\mathbf{S}) = s_{11}^2 + s_{22}^2 + s_{33}^2 + s_{44}^2 \]

For a symmetric matrix, this is also equal to the sum of its eigenvalues:

\[ \text{Total Variance} = \lambda_1 + \lambda_2 + \lambda_3 + \lambda_4 \] The proportion of total variance explained by the \(k\)-th principal component is:

\[ \text{Proportion}_k = \frac{\lambda_k}{\sum_{i=1}^{4} \lambda_i} \]

The cumulative variance explained by the first \(m\) components is:

\[ \text{Cumulative}_m = \frac{\sum_{i=1}^{m} \lambda_i}{\sum_{i=1}^{4} \lambda_i} \]

8. Interpretation in our Context

In the context of our math evaluation anxiety questionnaire:

  • The loading vector \(\mathbf{w}_1 = [w_{11}, w_{12}, w_{13}, w_{14}]^T\) reveals how the original items combine to form the primary latent dimension of anxiety. For example, if all loadings are positive and similar, \(z_1\) might represent .

  • The second component \(\mathbf{w}_2\) might contrast different types of anxiety. For instance, if \(w_{21}\) and \(w_{22}\) (test-related) are positive while \(w_{23}\) and \(w_{24}\) (pop quiz/homework) are negative, \(z_2\) might represent .

  • By examining the loadings, we can interpret the underlying psychological constructs that drive the correlations between the four questionnaire items.

13.2 Confirmatice Factor Analysis (CFA)

This appendix provides a detailed mathematical derivation of a Confirmatory Factor Analysis (CFA) model. The observed variables are nine items related to mathematical anxiety, which are hypothesized to load onto two latent factors: and .

1. Latent Factors and Observed Variables

We define two latent factors:

  • \(\eta_1\): Test Anxiety (TA)
  • \(\eta_2\): Learning Anxiety (LA)

We have nine observed variables (items/questions), \(y_1\) to \(y_9\):

  • \(y_1\): Having to use tables in the back of a math book.
  • \(y_2\): Thinking about a math test the day before you take it.
  • \(y_3\): Watching the teacher work out a math problem on the board.
  • \(y_4\): Taking a math test.
  • \(y_5\): Being given a homework assignment of many difficult problems that is due for the next class meeting.
  • \(y_6\): Listening to a lecture in math class.
  • \(y_7\): Listening to another student explain how to do a math problem.
  • \(y_8\): Being given a quiz on math without knowing in advance.
  • \(y_9\): Starting a new chapter in a math book.

2. Factor Loadings and Model Structure

We hypothesize the following factor structure:

  • Factor \(\eta_1\) (Test Anxiety) loads on items \(y_2\), \(y_4\), \(y_5\), and \(y_8\).
  • Factor \(\eta_2\) (Learning Anxiety) loads on items \(y_1\), \(y_3\), \(y_6\), \(y_7\), and \(y_9\).

The fundamental equation for a CFA model for a single observed variable \(y_i\) is:

\[ y_i = \nu_i + \lambda_{i1} \eta_1 + \lambda_{i2} \eta_2 + \epsilon_i \]

where:

  • \(\nu_i\) is the intercept for observed variable \(y_i\).
  • \(\lambda_{i1}\) is the factor loading of \(y_i\) on latent factor \(\eta_1\).
  • \(\lambda_{i2}\) is the factor loading of \(y_i\) on latent factor \(\eta_2\).
  • \(\epsilon_i\) is the unique factor (measurement error) for \(y_i\).

3. The Measurement Model in Matrix Form

The model for all nine observed variables can be written compactly in matrix form. We define the following vectors and matrices:

  • \(\mathbf{y} = (y_1, y_2, \dots, y_9)^T\) is a \(9 \times 1\) vector of observed variables.
  • \(\boldsymbol{\nu} = (\nu_1, \nu_2, \dots, \nu_9)^T\) is a \(9 \times 1\) vector of intercepts.
  • \(\boldsymbol{\eta} = (\eta_1, \eta_2)^T\) is a \(2 \times 1\) vector of latent factors.
  • \(\boldsymbol{\Lambda}\) is a \(9 \times 2\) matrix of factor loadings \(\lambda_{ij}\).
  • \(\boldsymbol{\epsilon} = (\epsilon_1, \epsilon_2, \dots, \epsilon_9)^T\) is a \(9 \times 1\) vector of measurement errors.

The full measurement model is:

\[ \mathbf{y} = \boldsymbol{\nu} + \boldsymbol{\Lambda} \boldsymbol{\eta} + \boldsymbol{\epsilon} \]

Given our hypothesized factor structure, the loading matrix \(\boldsymbol{\Lambda}\) has a specific form with many elements fixed to zero. To ensure model identification, we need to set the scale of each latent variable. This is typically done by , where the variance of the latent factor is fixed to 1, or by method, where one loading per factor is fixed to 1. We will use the latter.

Let us define:

  • \(y_2\) as the marker variable for \(\eta_1\) (Test Anxiety), so \(\lambda_{21} = 1\).
  • \(y_1\) as the marker variable for \(\eta_2\) (Learning Anxiety), so \(\lambda_{12} = 1\).

The \(\boldsymbol{\Lambda}\) matrix is then:

\[ \boldsymbol{\Lambda} = \begin{bmatrix} 0 & 1 \\ % y1 loads on eta2 (LA) 1 & 0 \\ % y2 loads on eta1 (TA) 0 & \lambda_{32} \\ % y3 loads on eta2 (LA) \lambda_{41} & 0 \\ % y4 loads on eta1 (TA) \lambda_{51} & 0 \\ % y5 loads on eta1 (TA) 0 & \lambda_{62} \\ % y6 loads on eta2 (LA) 0 & \lambda_{72} \\ % y7 loads on eta2 (LA) \lambda_{81} & 0 \\ % y8 loads on eta1 (TA) 0 & \lambda_{92} \\ % y9 loads on eta2 (LA) \end{bmatrix} \]

4. Model Assumptions

The CFA model relies on several key assumptions:

  • The errors have a mean of zero: \(E(\boldsymbol{\epsilon}) = \mathbf{0}\).

    The errors are uncorrelated with the factors: \(\mathrm{Cov}(\boldsymbol{\eta}, \boldsymbol{\epsilon}) = \mathbf{0}\).

  • The errors may be correlated with each other, but in a basic model, we often assume they are uncorrelated: \(\boldsymbol{\Theta}_{\epsilon} = \mathrm{Cov}(\boldsymbol{\epsilon}) = \mathrm{diag}(\theta_{11}, \theta_{22}, \dots, \theta_{99})\), where \(\theta_{ii} = \mathrm{Var}(\epsilon_i)\).

5. Derivation of the Implied Covariance Matrix

The core of CFA is to model the population covariance matrix of the observed variables, \(\boldsymbol{\Sigma}\). The model-implied covariance matrix, denoted \(\boldsymbol{\Sigma}(\boldsymbol{\theta})\), is a function of the model parameters \(\boldsymbol{\theta}\) (loadings, factor variances/covariances, error variances).

Let \(\boldsymbol{\Psi}\) be the \(2 \times 2\) covariance matrix of the latent factors:

\[ \boldsymbol{\Psi} = \mathrm{Cov}(\boldsymbol{\eta}) = \begin{bmatrix} \psi_{11} & \psi_{12} \\ \psi_{21} & \psi_{22} \end{bmatrix} = \begin{bmatrix} \mathrm{Var}(\eta_1) & \mathrm{Cov}(\eta_1, \eta_2) \\ \mathrm{Cov}(\eta_1, \eta_2) & \mathrm{Var}(\eta_2) \end{bmatrix} \]

The implied covariance matrix \(\boldsymbol{\Sigma}(\boldsymbol{\theta})\) is derived as follows:

\[ \begin{align*} \boldsymbol{\Sigma}(\boldsymbol{\theta}) &= \mathrm{Cov}(\mathbf{y}) \\ &= \mathrm{Cov}(\boldsymbol{\nu} + \boldsymbol{\Lambda}\boldsymbol{\eta} + \boldsymbol{\epsilon}) \\ &= \mathrm{Cov}(\boldsymbol{\Lambda}\boldsymbol{\eta} + \boldsymbol{\epsilon}) \quad \text{(since } \boldsymbol{\nu} \text{ is a constant)} \\ &= \mathrm{Cov}(\boldsymbol{\Lambda}\boldsymbol{\eta}) + \mathrm{Cov}(\boldsymbol{\epsilon}) + \mathrm{Cov}(\boldsymbol{\Lambda}\boldsymbol{\eta}, \boldsymbol{\epsilon}) + \mathrm{Cov}(\boldsymbol{\epsilon}, \boldsymbol{\Lambda}\boldsymbol{\eta}) \end{align*} \]

Using assumption 2 (\(\mathrm{Cov}(\boldsymbol{\eta}, \boldsymbol{\epsilon}) = \mathbf{0}\)), the cross-terms vanish:

\[ \mathrm{Cov}(\boldsymbol{\Lambda}\boldsymbol{\eta}, \boldsymbol{\epsilon}) = \boldsymbol{\Lambda} \mathrm{Cov}(\boldsymbol{\eta}, \boldsymbol{\epsilon}) = \mathbf{0}, \quad \mathrm{Cov}(\boldsymbol{\epsilon}, \boldsymbol{\Lambda}\boldsymbol{\eta}) = \mathbf{0} \]

Therefore,

\[ \begin{align*} \boldsymbol{\Sigma}(\boldsymbol{\theta}) &= \mathrm{Cov}(\boldsymbol{\Lambda}\boldsymbol{\eta}) + \mathrm{Cov}(\boldsymbol{\epsilon}) \\ &= \boldsymbol{\Lambda} \mathrm{Cov}(\boldsymbol{\eta}) \boldsymbol{\Lambda}^T + \boldsymbol{\Theta}_{\epsilon} \\ &= \boldsymbol{\Lambda} \boldsymbol{\Psi} \boldsymbol{\Lambda}^T + \boldsymbol{\Theta}_{\epsilon} \end{align*} \]

This is the fundamental equation for the implied covariance matrix in CFA:

\[ \boxed{\boldsymbol{\Sigma}(\boldsymbol{\theta}) = \boldsymbol{\Lambda} \boldsymbol{\Psi} \boldsymbol{\Lambda}^T + \boldsymbol{\Theta}_{\epsilon}} \]

6. Parameter Estimation and Model Identification

The goal of estimation is to find parameter values \(\hat{\boldsymbol{\theta}}\) such that \(\boldsymbol{\Sigma}(\hat{\boldsymbol{\theta}})\) is as close as possible to the sample covariance matrix \(\mathbf{S}\) obtained from the data.

For identification, the number of free parameters \(t\) must be less than or equal to the number of non-redundant elements in \(\mathbf{S}\), which is \(\frac{p(p+1)}{2}\) where \(p\) is the number of observed variables (\(p=9\)).

Let’s count our free parameters \(t\):

  • Factor Loadings (\(\boldsymbol{\Lambda}\))}: We fixed \(\lambda_{21}\) and \(\lambda_{12}\) to 1. We have 7 free loadings: \(\lambda_{32}\), \(\lambda_{41}\), \(\lambda_{51}\), \(\lambda_{62}\), \(\lambda_{72}\), \(\lambda_{81}\), \(\lambda_{92}\).

  • Latent Factor Covariances (\(\boldsymbol{\Psi}\))}: We have 3 free parameters: \(\psi_{11}\) (variance of TA), \(\psi_{22}\) (variance of LA), and \(\psi_{12}\) (covariance between TA and LA).

  • Error Variances (\(\boldsymbol{\Theta}_{\epsilon}\))}: We have 9 free parameters: \(\theta_{11}, \theta_{22}, \dots, \theta_{99}\).

Total free parameters: \(t = 7 + 3 + 9 = 19\).

The number of non-redundant elements in \(\mathbf{S}\) is \(\frac{9 \times (9+1)}{2} = 45\).

Since \(45 > 19\), the model is with \(df = 45 - 19 = 26\) degrees of freedom. This is a necessary condition for identification, and with the scaling constraints we placed, the model is identified.

7. Conclusion

This derivation has outlined the complete mathematical setup for a two-factor CFA model of mathematical anxiety. The model posits that the covariation among the nine observed items can be explained by two correlated latent factors. The next step would be to use an estimation algorithm (e.g., Maximum Likelihood) to find the parameter values that minimize the difference between \(\boldsymbol{\Sigma}(\boldsymbol{\theta})\) and the sample covariance matrix \(\mathbf{S}\), and then assess the model’s fit to the data.

13.3 Mathematical Formulation of SEM Model

1. Model Specification

Let the model consist of the following components:

  • Exogenous latent variables: \(\boldsymbol{\xi} = (\xi_1, \xi_2)^T\), where:
    • \(\xi_1\): Teacher-centered
    • \(\xi_2\): Student-centered
  • Endogenous latent variables: \(\boldsymbol{\eta} = (\eta_1, \eta_2)^T\), where:
    • \(\eta_1\): Math Evaluation Anxiety (MEA)
    • \(\eta_2\): Math Learning Anxiety (MLA)
  • Observed indicators for Teacher-centered: \(\mathbf{x}_1 = (x_1, x_2, x_3, x_4)^T\) where:
    • \(x_1\): Deductive
    • \(x_2\): Lecture
    • \(x_3\): Demonstration
    • \(x_4\): Repetitive
  • Observed indicators for Student-centered: \(\mathbf{x}_2 = (x_5, x_6, x_7)^T\) where:
    • \(x_5\): Cooperative
    • \(x_6\): Inductive
    • \(x_7\): Integrative
  • Observed indicators for MEA: \(\mathbf{y}_1 = (y_1, y_2, y_3, y_4)^T\) (MEA1-MEA4)
  • Observed indicators for MLA: \(\mathbf{y}_2 = (y_5, y_6, y_7, y_8, y_9)^T\) (MLA1, MLA3, MLA6, MLA7, MLA9)
  • Exogenous observed variables: \(\mathbf{w} = (w_1, w_2, w_3, w_4, w_5)^T\) where:
    • \(w_1\): Self-efficacy
    • \(w_2\): Technology
    • \(w_3\): Engagement
    • \(w_4\): Gender
    • \(w_5\): Resource

2. Measurement Models

For exogenous latent variables:

\[ \begin{align*} \mathbf{x} &= \boldsymbol{\Lambda}_x \boldsymbol{\xi} + \boldsymbol{\delta} \\ \begin{bmatrix} x_1 \\ x_2 \\ x_3 \\ x_4 \\ x_5 \\ x_6 \\ x_7 \end{bmatrix} &= \begin{bmatrix} \lambda_{1,1} & 0 \\ \lambda_{2,1} & 0 \\ \lambda_{3,1} & 0 \\ \lambda_{4,1} & 0 \\ 0 & \lambda_{5,2} \\ 0 & \lambda_{6,2} \\ 0 & \lambda_{7,2} \end{bmatrix} \begin{bmatrix} \xi_1 \\ \xi_2 \end{bmatrix} + \begin{bmatrix} \delta_1 \\ \delta_2 \\ \delta_3 \\ \delta_4 \\ \delta_5 \\ \delta_6 \\ \delta_7 \end{bmatrix} \end{align*} \]

For endogenous latent variables:

\[ \begin{align*} \mathbf{y} &= \boldsymbol{\Lambda}_y \boldsymbol{\eta} + \boldsymbol{\epsilon} \\ \begin{bmatrix} y_1 \\ y_2 \\ y_3 \\ y_4 \\ y_5 \\ y_6 \\ y_7 \\ y_8 \\ y_9 \end{bmatrix} &= \begin{bmatrix} \lambda_{1,1}^y & 0 \\ \lambda_{2,1}^y & 0 \\ \lambda_{3,1}^y & 0 \\ \lambda_{4,1}^y & 0 \\ 0 & \lambda_{5,2}^y \\ 0 & \lambda_{6,2}^y \\ 0 & \lambda_{7,2}^y \\ 0 & \lambda_{8,2}^y \\ 0 & \lambda_{9,2}^y \end{bmatrix} \begin{bmatrix} \eta_1 \\ \eta_2 \end{bmatrix} + \begin{bmatrix} \epsilon_1 \\ \epsilon_2 \\ \epsilon_3 \\ \epsilon_4 \\ \epsilon_5 \\ \epsilon_6 \\ \epsilon_7 \\ \epsilon_8 \\ \epsilon_9 \end{bmatrix} \end{align*} \]

3. Structural Model

The relationships between latent and observed variables:

\[ \begin{align*} \boldsymbol{\eta} &= \mathbf{B} \boldsymbol{\eta} + \boldsymbol{\Gamma} \boldsymbol{\xi} + \boldsymbol{\Gamma}_w \mathbf{w} + \boldsymbol{\zeta} \\ \begin{bmatrix} \eta_1 \\ \eta_2 \end{bmatrix} &= \begin{bmatrix} 0 & 0 \\ \beta_{21} & 0 \end{bmatrix} \begin{bmatrix} \eta_1 \\ \eta_2 \end{bmatrix} + \begin{bmatrix} \gamma_{11} & \gamma_{12} \\ \gamma_{21} & \gamma_{22} \end{bmatrix} \begin{bmatrix} \xi_1 \\ \xi_2 \end{bmatrix} + \begin{bmatrix} \gamma_{13} & \gamma_{14} & \gamma_{15} & \gamma_{16} & \gamma_{17} \\ \gamma_{23} & \gamma_{24} & \gamma_{25} & \gamma_{26} & \gamma_{27} \end{bmatrix} \begin{bmatrix} w_1 \\ w_2 \\ w_3 \\ w_4 \\ w_5 \end{bmatrix} + \begin{bmatrix} \zeta_1 \\ \zeta_2 \end{bmatrix} \end{align*} \]

4. Assumptions

  • The measurement errors are uncorrelated with the latent variables:

\[ \begin{align*} E(\boldsymbol{\delta}|\boldsymbol{\xi}) = \mathbf{0}, \quad E(\boldsymbol{\epsilon}|\boldsymbol{\eta}) = \mathbf{0} \end{align*} \]

  • The structural disturbances have zero mean and are uncorrelated with the exogenous variables:

\[ \begin{align*} E(\boldsymbol{\zeta}) = \mathbf{0}, \quad \text{Cov}(\boldsymbol{\zeta}, \boldsymbol{\xi}) = \mathbf{0}, \quad \text{Cov}(\boldsymbol{\zeta}, \mathbf{w}) = \mathbf{0} \end{align*} \]

  • The measurement errors and structural disturbances are mutually uncorrelated:

\[ \begin{align*} \text{Cov}(\boldsymbol{\delta}, \boldsymbol{\epsilon}) = \mathbf{0}, \quad \text{Cov}(\boldsymbol{\delta}, \boldsymbol{\zeta}) = \mathbf{0}, \quad \text{Cov}(\boldsymbol{\epsilon}, \boldsymbol{\zeta}) = \mathbf{0} \end{align*} \]

  • The measurement errors are mutually uncorrelated:

\[ \begin{align*} \text{Cov}(\boldsymbol{\delta}) = \boldsymbol{\Theta}_{\delta} = \text{diag}(\theta_{\delta,1}, \dots, \theta_{\delta,7}) \end{align*} \]

\[ \begin{align*} \text{Cov}(\boldsymbol{\epsilon}) = \boldsymbol{\Theta}_{\epsilon} = \text{diag}(\theta_{\epsilon,1}, \dots, \theta_{\epsilon,9}) \end{align*} \]

  • The structural disturbances have covariance matrix:

\[ \begin{align*} \text{Cov}(\boldsymbol{\zeta}) = \boldsymbol{\Psi} = \begin{bmatrix} \psi_{11} & \psi_{12} \\ \psi_{21} & \psi_{22} \end{bmatrix} \end{align*} \]

  • The exogenous latent variables have covariance matrix:

\[ \begin{align*} \text{Cov}(\boldsymbol{\xi}) = \boldsymbol{\Phi} = \begin{bmatrix} \phi_{11} & \phi_{12} \\ \phi_{21} & \phi_{22} \end{bmatrix} \end{align*} \]

  • The exogenous observed variables have covariance matrix:

\[ \begin{align*} \text{Cov}(\mathbf{w}) = \boldsymbol{\Phi}_w \end{align*} \]

  • All variables are multivariate normally distributed.

5. Implied Covariance Matrix

Let \(\boldsymbol{\theta}\) represent all model parameters. The implied covariance matrix of the observed variables \(\mathbf{z} = (\mathbf{x}^T, \mathbf{y}^T, \mathbf{w}^T)^T\) is:

\[ \begin{align*} \boldsymbol{\Sigma}(\boldsymbol{\theta}) = \begin{bmatrix} \boldsymbol{\Sigma}_{xx}(\boldsymbol{\theta}) & \boldsymbol{\Sigma}_{xy}(\boldsymbol{\theta}) & \boldsymbol{\Sigma}_{xw}(\boldsymbol{\theta}) \\ \boldsymbol{\Sigma}_{yx}(\boldsymbol{\theta}) & \boldsymbol{\Sigma}_{yy}(\boldsymbol{\theta}) & \boldsymbol{\Sigma}_{yw}(\boldsymbol{\theta}) \\ \boldsymbol{\Sigma}_{wx}(\boldsymbol{\theta}) & \boldsymbol{\Sigma}_{wy}(\boldsymbol{\theta}) & \boldsymbol{\Sigma}_{ww}(\boldsymbol{\theta}) \end{bmatrix} \end{align*} \]

where:

\[ \begin{align*} \boldsymbol{\Sigma}_{xx}(\boldsymbol{\theta}) &= \boldsymbol{\Lambda}_x \boldsymbol{\Phi} \boldsymbol{\Lambda}_x^T + \boldsymbol{\Theta}_{\delta} \\ \boldsymbol{\Sigma}_{yy}(\boldsymbol{\theta}) &= \boldsymbol{\Lambda}_y (\mathbf{I}-\mathbf{B})^{-1} (\boldsymbol{\Gamma} \boldsymbol{\Phi} \boldsymbol{\Gamma}^T + \boldsymbol{\Gamma}_w \boldsymbol{\Phi}_w \boldsymbol{\Gamma}_w^T + \boldsymbol{\Psi}) [(\mathbf{I}-\mathbf{B})^{-1}]^T \boldsymbol{\Lambda}_y^T + \boldsymbol{\Theta}_{\epsilon} \\ \boldsymbol{\Sigma}_{ww}(\boldsymbol{\theta}) &= \boldsymbol{\Phi}_w \\ \boldsymbol{\Sigma}_{xy}(\boldsymbol{\theta}) &= \boldsymbol{\Lambda}_x \boldsymbol{\Phi} \boldsymbol{\Gamma}^T [(\mathbf{I}-\mathbf{B})^{-1}]^T \boldsymbol{\Lambda}_y^T \\ \boldsymbol{\Sigma}_{xw}(\boldsymbol{\theta}) &= \boldsymbol{\Lambda}_x \text{Cov}(\boldsymbol{\xi}, \mathbf{w}) \\ \boldsymbol{\Sigma}_{yw}(\boldsymbol{\theta}) &= \boldsymbol{\Lambda}_y (\mathbf{I}-\mathbf{B})^{-1} (\boldsymbol{\Gamma} \text{Cov}(\boldsymbol{\xi}, \mathbf{w}) + \boldsymbol{\Gamma}_w \boldsymbol{\Phi}_w) \end{align*} \]

6. Likelihood Function

Assuming multivariate normality of the observed variables \(\mathbf{z} \sim N(\boldsymbol{\mu}, \boldsymbol{\Sigma}(\boldsymbol{\theta}))\), the likelihood function for a sample of \(n\) independent observations is:

\[ \begin{align*} L(\boldsymbol{\theta}) &= \prod_{i=1}^n (2\pi)^{-p/2} |\boldsymbol{\Sigma}(\boldsymbol{\theta})|^{-1/2} \exp\left[-\frac{1}{2}(\mathbf{z}_i - \boldsymbol{\mu})^T \boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} (\mathbf{z}_i - \boldsymbol{\mu})\right] \end{align*} \]

where \(p = 7 + 9 + 5 = 21\) is the total number of observed variables.

The log-likelihood function is:

\[ \begin{align*} \ell(\boldsymbol{\theta}) &= -\frac{np}{2} \log(2\pi) - \frac{n}{2} \log|\boldsymbol{\Sigma}(\boldsymbol{\theta})| \\ &\quad - \frac{1}{2} \sum_{i=1}^n (\mathbf{z}_i - \boldsymbol{\mu})^T \boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1} (\mathbf{z}_i - \boldsymbol{\mu}) \end{align*} \]

For estimation, we typically use the discrepancy function:

\[ \begin{align*} F_{ML}(\boldsymbol{\theta}) &= \log|\boldsymbol{\Sigma}(\boldsymbol{\theta})| + \text{tr}(\mathbf{S} \boldsymbol{\Sigma}(\boldsymbol{\theta})^{-1}) - \log|\mathbf{S}| - p \end{align*} \]

where \(\mathbf{S}\) is the sample covariance matrix.

7. Parameters to Estimate

The model parameters include:

  • Factor loadings: \(\lambda_{ij}\) in \(\boldsymbol{\Lambda}_x\) and \(\boldsymbol{\Lambda}_y\)
  • Structural coefficients: \(\beta_{ij}\) in \(\mathbf{B}\), \(\gamma_{ij}\) in \(\boldsymbol{\Gamma}\), \(\gamma_{ij}^w\) in \(\boldsymbol{\Gamma}_w\)
  • Variances and covariances: \(\phi_{ij}\) in \(\boldsymbol{\Phi}\), \(\psi_{ij}\) in \(\boldsymbol{\Psi}\), \(\phi_{w,ij}\) in \(\boldsymbol{\Phi}_w\)
  • Measurement error variances: \(\theta_{\delta,i}\) in \(\boldsymbol{\Theta}_{\delta}\), \(\theta_{\epsilon,i}\) in \(\boldsymbol{\Theta}_{\epsilon}\)

Typically, we set one loading per latent variable to 1 for identification.

8. Model Identification

The model is identified if:

  • Each latent variable has at least 3 indicators (satisfied)
  • The scale of each latent variable is set by fixing one loading to 1
  • The model meets the order condition and rank condition for identification
LS0tDQp0aXRsZTogIk1hdGhlbWF0aWNzIEFueGlldHkgU3VydmV5IFJlcG9ydCINCmF1dGhvcjogIkNoZW5nIFBlbmcgJiBMYXVyYSBQeWF0dCINCmRhdGU6ICJXZXN0IENoZXN0ZXIgVW5pdmVyc2l0eSINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jX2NvbGxhcHNlZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgc21vb3RoX3Njcm9sbDogeWVzDQogICAgdGhlbWU6IGx1bWVuDQogIHBkZl9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICBmaWdfd2lkdGg6IDMNCiAgICBmaWdfaGVpZ2h0OiAzDQogIHdvcmRfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIGtlZXBfbWQ6IHllcw0KZWRpdG9yX29wdGlvbnM6IA0KICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lDQotLS0NCg0KYGBge2NzcywgZWNobyA9IEZBTFNFfQ0KI1RPQzo6YmVmb3JlIHsNCiAgY29udGVudDogIlRhYmxlIG9mIENvbnRlbnRzIjsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtc2l6ZTogMS4yZW07DQogIGRpc3BsYXk6IGJsb2NrOw0KICBjb2xvcjogbmF2eTsNCiAgbWFyZ2luLWJvdHRvbTogMTBweDsNCn0NCg0KDQpkaXYjVE9DIGxpIHsgICAgIC8qIHRhYmxlIG9mIGNvbnRlbnQgICovDQogICAgbGlzdC1zdHlsZTp1cHBlci1yb21hbjsNCiAgICBiYWNrZ3JvdW5kLWltYWdlOm5vbmU7DQogICAgYmFja2dyb3VuZC1yZXBlYXQ6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOjA7DQp9DQoNCmgxLnRpdGxlIHsgICAgLyogbGV2ZWwgMSBoZWFkZXIgb2YgdGl0bGUgICovDQogIGZvbnQtc2l6ZTogMjJweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQogIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsNCn0NCg0KaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxNXB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6IHN5c3RlbS11aTsNCiAgY29sb3I6IG5hdnk7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDQuZGF0ZSB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMThweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsNCiAgY29sb3I6IERhcmtCbHVlOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmgxIHsgLyogSGVhZGVyIDEgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDIwcHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoMiB7IC8qIEhlYWRlciAyIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmgzIHsgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE2cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDQgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTRweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KLyogQWRkIGRvdHMgYWZ0ZXIgbnVtYmVyZWQgaGVhZGVycyAqLw0KLmhlYWRlci1zZWN0aW9uLW51bWJlcjo6YWZ0ZXIgew0KICBjb250ZW50OiAiLiI7DQoNCmJvZHkgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9DQoNCi5oaWdobGlnaHRtZSB7IGJhY2tncm91bmQtY29sb3I6eWVsbG93OyB9DQoNCnAgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9DQoNCn0NCmBgYA0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMgY29kZSBjaHVuayBzcGVjaWZpZXMgd2hldGhlciB0aGUgUiBjb2RlLCB3YXJuaW5ncywgYW5kIG91dHB1dCANCiMgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IGZpbGVzLg0KaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpDQogICBsaWJyYXJ5KGtuaXRyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwYW5kZXIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicGFuZGVyIikNCiAgIGxpYnJhcnkocGFuZGVyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KfQ0KaWYgKCFyZXF1aXJlKCJHR2FsbHkiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiR0dhbGx5IikNCmxpYnJhcnkoR0dhbGx5KQ0KfQ0KIyBJbnN0YWxsIGFuZCBsb2FkIHRoZSBwYWNrYWdlDQppZiAoIXJlcXVpcmUoImljYSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoImljYSIpDQpsaWJyYXJ5KGljYSkNCn0NCmlmICghcmVxdWlyZSgiZmFzdElDQSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoImZhc3RJQ0EiKQ0KICBsaWJyYXJ5KGZhc3RJQ0EpDQp9DQppZiAoIXJlcXVpcmUoIk1BU1MiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJNQVNTIikNCiAgbGlicmFyeShNQVNTKQ0KfQ0KaWYgKCFyZXF1aXJlKCJnZ3Bsb3QyIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpDQogIGxpYnJhcnkoZ2dwbG90MikNCn0gDQppZiAoIXJlcXVpcmUoInBsb3RseSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInBsb3RseSIpDQogIGxpYnJhcnkocGxvdGx5KQ0KfSANCmlmICghcmVxdWlyZSgibGF2YWFuIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygibGF2YWFuIikNCiAgbGlicmFyeShsYXZhYW4pDQp9IA0KaWYgKCFyZXF1aXJlKCJzZW1Ub29scyIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInNlbVRvb2xzIikNCiAgbGlicmFyeShzZW1Ub29scykNCn0NCmlmICghcmVxdWlyZSgic3RyaW5nciIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInN0cmluZ3IiKQ0KICBsaWJyYXJ5KHN0cmluZ3IpDQp9DQppZiAoIXJlcXVpcmUoInJlc2hhcGUyIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygicmVzaGFwZTIiKQ0KICBsaWJyYXJ5KHJlc2hhcGUyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwc3ljaCIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInBzeWNoIikNCiAgbGlicmFyeShwc3ljaCkNCn0NCmlmICghcmVxdWlyZSgiZ2dyaWRnZXMiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3JpZGdlcyIpDQogIGxpYnJhcnkoZ2dyaWRnZXMpDQp9DQppZiAoIXJlcXVpcmUoIlJDb2xvckJyZXdlciIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoIlJDb2xvckJyZXdlciIpDQogIGxpYnJhcnkoUkNvbG9yQnJld2VyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJoZWF0bWFwbHkiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJoZWF0bWFwbHkiKQ0KICBsaWJyYXJ5KGhlYXRtYXBseSkNCn0NCmlmICghcmVxdWlyZSgic2VtUGxvdCIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInNlbVBsb3QiKQ0KICBsaWJyYXJ5KHNlbVBsb3QpDQp9DQppZiAoIXJlcXVpcmUoImxhdmFhblBsb3QiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJsYXZhYW5QbG90IikNCiAgbGlicmFyeShsYXZhYW5QbG90KQ0KfQ0KaWYgKCFyZXF1aXJlKCJib290IikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygiYm9vdCIpDQogIGxpYnJhcnkoYm9vdCkNCn0NCmlmICghcmVxdWlyZSgibGVhcHMiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJsZWFwcyIpDQogIGxpYnJhcnkobGVhcHMpDQp9DQojIyBsaWJyYXJ5KGxlYXBzKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICAjIGluY2x1ZGUgY29kZSBjaHVuayBpbiB0aGUgb3V0cHV0IGZpbGUNCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgIyBzb21ldGltZXMsIHlvdSBjb2RlIG1heSBwcm9kdWNlIHdhcm5pbmcgbWVzc2FnZXMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeW91IGNhbiBjaG9vc2UgdG8gaW5jbHVkZSB0aGUgd2FybmluZyBtZXNzYWdlcyBpbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRoZSBvdXRwdXQgZmlsZS4gDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsICAgICMgeW91IGNhbiBhbHNvIGRlY2lkZSB3aGV0aGVyIHRvIGluY2x1ZGUgdGhlIG91dHB1dA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluIHRoZSBvdXRwdXQgZmlsZS4NCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BDQogICAgICAgICAgICAgICAgICAgICAgKSAgDQpgYGANCg0KXA0KDQojIEludHJvZHVjdGlvbg0KDQpUaGUgc3ViamVjdCBvZiBtYXRoZW1hdGljcyBjYXVzZXMgZmVhciBhbmQgZGlmZmljdWx0eSBmb3IgYSB3aWRlIHJhbmdlIG9mIHN0dWRlbnRzLiBXZSBvZnRlbiBoZWFyIHN0dWRlbnRzIGNsYWltLCDigJxJIGRvbuKAmXQgbGlrZSBtYXRo4oCdLCDigJxJ4oCZbSBqdXN0IG5vdCBnb29kIGF0IG1hdGjigJ0sIOKAnEnigJltIG5vdCBhIG1hdGggcGVyc29u4oCdLCBvciDigJxJIHdhc27igJl0IGJvcm4gd2l0aCB0aGUgbWF0aCBnZW5l4oCdLCBldGMuIEFsdGhvdWdoIHRoZXNlIGNsYWltcyBhcmUgbm90IHBlcmZlY3QgaW5kaWNhdG9ycyBvZiBtYXRoIGFueGlldHksIHN0dWRlbnRzIHdobyBoYXZlIHRoZXNlIGZpeGVkIG1pbmRzZXRzIHdpbGwgYmUgbW9yZSBsaWtlbHkgdG8gZXhwZXJpZW5jZSBtYXRoIGFueGlldHkuDQoNCldoaWxlIG1hdGggYW54aWV0eSBjYW4gaGF2ZSBhIHNlcmlvdXMgaW1wYWN0IG9uIGFjYWRlbWljIHBlcmZvcm1hbmNlLCBpdCBkb2VzIG5vdCBtZWFuIGEgbGFjayBvZiBtYXRoZW1hdGljcyBhYmlsaXR5LiBQcm9mLiBMYXVyZW50IFNjaHdhcnR6IGV4cGVyaWVuY2VkIG1hdGggYW54aWV0eSBpbiB0aGUgMTF0aCBncmFkZSwgYnV0IHRoaXMgZGlkIG5vdCBwcmV2ZW50IGhpbSBmcm9tIGJlY29taW5nIGEgcHJvbWluZW50IG1hdGhlbWF0aWNpYW4uIEluIGZhY3QsIGhlIHdvbiB0aGUgRmllbGRzIE1vZGVsICh0aGUgbWF0aGVtYXRpY2lhbuKAmXMgTm9iZWwgUHJpemUpIGluIDE5NTAuIEVmZmVjdGl2ZWx5IG1hbmFnaW5nIG1hdGggYW54aWV0eSByZXF1aXJlcyBhIGRlZXAgdW5kZXJzdGFuZGluZyBvZiBtYXRoIGFueGlldHkuDQoNClRoaXMgcHJvamVjdCBhaW1zIHRvIGlkZW50aWZ5IGZhY3RvcnMgdGhhdCBhcmUgc3Ryb25nbHkgYXNzb2NpYXRlZCB3aXRoIG1hdGggYW54aWV0eSBhbmQgdXNlIHRoZW0gdG8gcmVkdWNlIG1hdGggYW54aWV0eSBhbmQsIGNvbnNlcXVlbnRseSwgaW1wcm92ZSBhY2FkZW1pYyBwZXJmb3JtYW5jZS4gU3BlY2lmaWNhbGx5Og0KDQoxLglUaGUgcmVzdWx0cyBvZiB0aGlzIHByb2plY3Qgd2lsbCBjb250cmlidXRlIHRvIHRoZSBib2R5IG9mIGV4aXN0aW5nIGtub3dsZWRnZS4NCg0KMi4JSWRlbnRpZmljYXRpb24gb2YgZW52aXJvbm1lbnRhbCBmYWN0b3JzIGFpZHMgdGhlIGRldmVsb3BtZW50IG9mIGludGVydmVudGlvbiB0b29scyBmb3IgZWR1Y2F0b3JzIGFuZCBzdXBwb3J0IHN0YWZmIHRvIGhlbHAgc3R1ZGVudHMgcmVkdWNlIG1hdGggYW54aWV0eSBhbmQgaW1wcm92ZSB0aGVpciBhY2FkZW1pYyBwZXJmb3JtYW5jZS4NCg0KMy4JVGhlIG91dGNvbWVzIG9mIHRoaXMgcHJvamVjdCBjYW4gYmUgdXNlZCB0byBpbXBsaWNpdGx5IGltcHJvdmUgcmV0ZW50aW9uLg0KDQojIExpdGVyYXR1cmUgUmV2aWV3DQoNCk1hdGhlbWF0aWNzIGFueGlldHkgaW52b2x2ZXMgZmVlbGluZ3Mgb2YgZmVhciwgdGVuc2lvbiwgYXBwcmVoZW5zaW9uLCBhbmQgcGh5c2lvbG9naWNhbCByZWFjdGl2aXR5IGludGVyZmVyaW5nIHdoZW4gaW5kaXZpZHVhbHMgZW5nYWdlIHdpdGggbnVtYmVyIG1hbmlwdWxhdGlvbiBhbmQgbWF0aGVtYXRpY2FsIHByb2JsZW0tc29sdmluZyAoc2VlLCBmb3IgZXhhbXBsZSwgUGxldHplciBldCBhbC4gMjAxNikuIEluIHRoZSBVLlMuLCBhbiBlc3RpbWF0ZWQgMjUlIG9mIGZvdXIteWVhciBjb2xsZWdlIHN0dWRlbnRzIGFuZCB1cCB0byA4MCUgb2YgY29tbXVuaXR5IGNvbGxlZ2Ugc3R1ZGVudHMgc3VmZmVyIGZyb20gYSBtb2RlcmF0ZSB0byBhIGhpZ2ggZGVncmVlIG9mIG1hdGhlbWF0aWNzIGFueGlldHkgKENoYW5nICYgQmVpbG9jaywgMjAxNikuIFRoZSBmcmVxdWVuY3kgb2YgbmVnYXRpdmUgZWZmZWN0cyBvZiBtYXRoIGFueGlldHkgb24gY29sbGVnZSBzdHVkZW50cyBpcyBpbmNyZWFzaW5nLg0KDQpUaGUgZWFybGllc3QgcmVzZWFyY2ggb24gbWF0aCBhbnhpZXR5IGNhbiBiZSB0cmFjZWQgYmFjayB0byBHb3VnaCAoMTk1NCkgd2hvIHVzZWQgdGhlIHRlcm0gbWF0aGVtYXBob2JpYS4gVGhlIHRlcm0gbWF0aCBhbnhpZXR5IHdhcyBmaXJzdCB1c2VkIGJ5IERyZWdlciBhbmQgQWlrZW4gKDE5NTcpLiBUaGUgZmlyc3QgZGVmaW5pdGlvbiBvZiBtYXRoIGFueGlldHkgaXMgY3JlZGl0ZWQgdG8gUmljaGFyZHNvbiBhbmQgU3Vpbm4gKDE5NzIpLCB3aG8gZGVzY3JpYmVkIG1hdGggYW54aWV0eSBhcyDigJxmZWVsaW5ncyBvZiB0ZW5zaW9uIGFuZCBhbnhpZXR5IHRoYXQgaW50ZXJmZXJlIHdpdGggdGhlIG1hbmlwdWxhdGlvbiBvZiBudW1iZXJzIGFuZCBzb2x2aW5nIG9mIG1hdGhlbWF0aWNhbCBwcm9ibGVtcyBpbiBhIHdpZGUgdmFyaWV0eSBvZiBvcmRpbmFyeSBsaWZlIGFuZCBhY2FkZW1pYyBzaXR1YXRpb25z4oCdLiAgDQoNCkluIHRoZSBwYXN0IDcwIHllYXJzLCBudW1lcm91cyBhdXRob3JzIGNvbmR1Y3RlZCBleHRlbnNpdmUgcmVzZWFyY2ggb24gbWF0aCBhbnhpZXR5LiBQYXJ0aWN1bGFybHksIGluIHRoZSBwYXN0IDIwIHllYXJzLCByZXNlYXJjaGVycyBmcm9tIGRpZmZlcmVudCBkaXNjaXBsaW5lcyBpbmNsdWRpbmcgbWF0aGVtYXRpY3MgaGF2ZSBpbnZlc3RpZ2F0ZWQgdGhlIGFzc29jaWF0aW9uIGJldHdlZW4gbWF0aCBhbnhpZXR5IGFuZCBtYXRoIGFjaGlldmVtZW50LCB0aGUgY2F1c2VzIG9mIG1hdGggYW54aWV0eSwgY2hhcmFjdGVyaXN0aWNzIG9mIHN0dWRlbnRzIHRoYXQgaW5jcmVhc2Ugc3VzY2VwdGliaWxpdHkgdG8gbWF0aCBhbnhpZXR5LCBhbmQgZWZmb3J0cyB0aGF0IGVkdWNhdG9ycyBjYW4gdGFrZSB0byByZW1lZHkgaXQuDQoNCk1hdGggYW54aWV0eSBpcyByZWFsLiBJdHMgbmVnYXRpdmUgaW1wYWN0IG9uIHN0dWRlbnRz4oCZIGFjYWRlbWljIHBlcmZvcm1hbmNlIGFuZCB0aGVpciBmdXR1cmUgcHJvZmVzc2lvbmFsIGxpZmUgaXMgcHJvZm91bmQuIEV4dGVuc2l2ZSByZXNlYXJjaCBwdWJsaWNhdGlvbnMgc2luY2UgMjAwMCBoYXZlIHNob3duIHRoYXQgbWF0aCBhbnhpZXR5IHJlbGF0ZXMgaW52ZXJzZWx5IHRvIHBvc2l0aXZlIGF0dGl0dWRlcyB0b3dhcmQgbWF0aGVtYXRpY3MgYW5kIGlzIGJvdW5kIGRpcmVjdGx5IHRvIGF2b2lkYW5jZSBvZiB0aGUgc3ViamVjdCAoc2VlIGZvciBleGFtcGxlLCBTZWdvb2wgZXQgYWwuLCAyMDEzKS4gSXQgYWZmZWN0cyBib3RoIG1hdGggYW5kIG92ZXJhbGwgYWNhZGVtaWMgcGVyZm9ybWFuY2Ugc2luY2UgbWF0aCBhbnhpZXR5IGxlYWRzIHRvIHRoZSBkcmFpbmFnZSBvZiBjb2duaXRpdmUgcmVzb3VyY2VzLCBtb3RpdmF0aW9uIHJlZHVjdGlvbiwgYW5kIHN0cmF0ZWd5IGltcGFpcm1lbnQgKEtsZWUgZXQgYWwuLCAyMDIyKS4NCg0KTWF0aCBhbnhpZXR5IGNhbiBhbHNvIGxlYWQgdG8gcG9vciBhY2FkZW1pYyBwZXJmb3JtYW5jZSBhbmQgY291cnNlIHdpdGhkcmF3YWwsIHB1dHRpbmcgc3R1ZGVudHMgYmVoaW5kIHNjaGVkdWxlIGFuZCBpbmNyZWFzaW5nIHRoZSByaXNrIG9mIGRyb3Agb3V0LCB3aGljaCByZWR1Y2VzIHN0dWRlbnQgcmV0ZW50aW9uIHJhdGVzLiBXaWxzb24gKDIwMTMpIHN0dWRpZWQgbWF0aCBhbnhpZXR5IG9mIG1hdHVyZS1hZ2UgcHJlLXNlcnZpY2UgdGVhY2hlcnMgYXMgYSBwb3RlbnRpYWwgY29udHJpYnV0aW5nIGZhY3RvciB0aGF0IGltcGFjdHMgc3R1ZGVudCByZXRlbnRpb24uIERha2VyIGV0IGFsLiAoMjAyMSkgcmVjZW50bHkgc3R1ZGllZCB0aGUgaW1wYWN0IG9mIG1hdGggYW54aWV0eSBvbiBmaXJzdC15ZWFyIFNURU0gc3R1ZGVudHMgYW5kIGNvbmNsdWRlZCB0aGF0IG1hdGggYW54aWV0eSBwcmVkaWN0cyBTVEVNIGF2b2lkYW5jZSBhbmQgdW5kZXJwZXJmb3JtYW5jZSB0aHJvdWdob3V0IHRoZSB1bml2ZXJzaXR5LCBpbmRlcGVuZGVudGx5IG9mIG1hdGggYWJpbGl0eS4NCg0KQSB3ZWFsdGggb2YgZW1waXJpY2FsIHN0dWRpZXMgb24gdmFyaW91cyBhc3BlY3RzIG9mIG1hdGggYW54aWV0eSBoYXZlIGJlZW4gY29uZHVjdGVkIHNpbmNlIERyZWdlciAmIEFpa2Vu4oCZcyAoMTk1Nykgc2VtaW5hbCB3b3JrLiBEdWUgdG8gdGhlIGNvbXBsZXggcGF0aHdheXMgdG93YXJkIHRoZSBkZXZlbG9wbWVudCBvZiBtYXRoIGFueGlldHkgYW5kIGl0cyBsaW5rcyB3aXRoIGFjaGlldmVtZW50cyBhbmQgY29uZm91bmRlcnMsIHRoZSBvcmlnaW5zIGFuZCBvdXRjb21lcyBvZiBtYXRoIGFueGlldHkgYXJlIHN0aWxsIG5vdCBmdWxseSB1bmRlcnN0b29kLg0KDQpSZWNlbnQgYW5kIG9uZ29pbmcgcmVzZWFyY2ggZm9jdXNlcyBvbiB0aGUgZGV2ZWxvcG1lbnQgYW5kIGR5bmFtaWMgaW50ZXJwbGF5IGJldHdlZW4gZmFjdG9ycyB0aGF0IGNhdXNlIG1hdGggYW54aWV0eS4gTW9zdCBvZiB0aGUgcmVzZWFyY2ggY2FuIGJlIGNsYXNzaWZpZWQgaW50byB0aHJlZSBjYXRlZ29yaWVzOiBzaXR1YXRpb25hbCwgZGlzcG9zaXRpb25hbCwgYW5kIGVudmlyb25tZW50YWwgKE/igJlMZWFyeSBldCBhbC4sIDIwMTcpLiBUaGUgY3VycmVudCBwcm9qZWN0IHdpbGwgZXhwbG9yZSBhbGwgdGhyZWUgdHlwZXMgb2YgZmFjdG9ycywgYnV0IHRoZSBwcmltYXJ5IGZvY3VzIGlzIG9uIHRoZSBlbnZpcm9ubWVudGFsIGZhY3RvcnMgc3VjaCBhcyBwcmlvciBwZXJjZXB0aW9ucywgYXR0aXR1ZGVzLCBhbmQgZXhwZXJpZW5jZXMgdGhhdCBoYXZlIGFmZmVjdGVkIHRoZSBpbmRpdmlkdWFsLg0KDQojIFJlc2VhcmNoIE9iamVjdGl2ZXMNCg0KU2luY2UgbG93ZXIgbWF0aGVtYXRpY3MgYWNoaWV2ZW1lbnQgcHJlZGljdHMgaGlnaGVyIHN1YnNlcXVlbnQgbWF0aCBhbnhpZXR5IGFuZCBoaWdoZXIgbWF0aCBhbnhpZXR5IHByZWRpY3RzIGxvd2VyIGZ1dHVyZSBhY2hpZXZlbWVudCwgcmVkdWNpbmcgbWF0aCBhbnhpZXR5IHdpbGwgaGVscCBzdHVkZW50cyBkZXZlbG9wIGEgcG9zaXRpdmUgYXR0aXR1ZGUgdG8gbWF0aGVtYXRpY3MsIGJ1aWxkIGNvbmZpZGVuY2UsIGJvb3N0IG1vdGl2YXRpb24sIGFuZCBjb25zZXF1ZW50bHkgaW1wcm92ZSB0aGVpciBhY2hpZXZlbWVudHMuIFRoaXMgc3R1ZHkgYWltZWQgdG8gaWRlbnRpZnkgdGhlIGZhY3RvcnMgdGhhdCBjYW4gcmVkdWNlIG1hdGggYW54aWV0eSBpbiBjb2xsZWdlIHN0dWRlbnRzLiBTcGVjaWZpYyBvYmplY3RpdmVzIGFyZQ0KDQoqKk9iamVjdGl2ZSAxKio6IEFkb3B0aW5nIHdlbGwtZXN0YWJsaXNoZWQgcHN5Y2hvbWV0cmljIHN1cnZleSBpbnN0cnVtZW50cyBBTUFTIGFuZCBzZWxmLWVmZmljYWN5IGluc3RydW1lbnRzIHRvIGNvbGxlY3QgbWF0aCBhbnhpZXR5IGFuZCBzZWxmLWVmZmljYWN5IGRhdGEuDQoNCioqT2JqZWN0aXZlIDIqKjogSW5jbHVkZSBzb21lIGRlbW9ncmFwaGljIGNoYXJhY3RlcmlzdGljcyBzdWNoIGFzIGFnZSBhbmQgZ2VuZGVyIHRvIGNvbXBhcmUgdGhlIHJlc3VsdHMgd2l0aCB0aGF0IG9mIGV4aXN0aW5nIHJlc2VhcmNoIGFuZCB1c2UgdGhlbSBhcyBhIGJhc2VsaW5lLg0KDQoqKk9iamVjdGl2ZSAzKio6IFRlYWNoaW5nIHN0cmF0ZWdpZXMgY2FuIHJlZHVjZSBtYXRoIGFueGlldHkgYW5kIGltcHJvdmUgbGVhcm5pbmcgb3V0Y29tZXMuIFdlIHdpbGwgaW52ZXN0aWdhdGUgc2V2ZXJhbCBkaWZmZXJlbnQgc3RyYXRlZ2llcyBpbiBtYXRoZW1hdGljcyB0ZWFjaGluZyBzdWNoIGFzIGNvbmNlcHR1YWwsIHByb2NlZHVyZSwgZXRjLiwgdG8gc2VlIGlmIHRoZXNlIHN0cmF0ZWdpZXMgYWZmZWN0IHRoZSBsZXZlbCBvZiBtYXRoIGFueGlldHkuDQoNCioqT2JqZWN0aXZlIDQqKjogRWZmZWN0aXZlbHkgdXNpbmcgdGhlIHRlY2hub2xvZ2llcyBjYW4gcmVkdWNlIG1hdGggYW54aWV0eS4gVGhlIHJlY2VudGx5IGRldmVsb3BlZCBlZHVjYXRpb25hbCB0ZWNobm9sb2dpZXMgZHVyaW5nIHRoZSBwYW5kZW1pYyBoYXZlIG5vdCBiZWVuIGRpc2N1c3NlZCBpbiB0aGUgbGl0ZXJhdHVyZSBvbiBtYXRoIGFueGlldHkuIFdlIHdpbGwgaW52ZXN0aWdhdGUgaG93IHRoZXNlIG5ldyB0ZWNobm9sb2dpZXMgYWZmZWN0IG1hdGggYW54aWV0eS4NCg0KKipPYmplY3RpdmUgNSoqOiBMZWFybmluZyBtb2RhbGl0aWVzIGFuZCBzdHlsZXMgYXJlIGFsc28gYXNzb2NpYXRlZCB3aXRoIG1hdGggYW54aWV0eS4gTW9zdCBvZiB0aGUgcmVzZWFyY2ggaW4gdGhpcyBkaXJlY3Rpb24gaXMgYmFzZWQgb24gaGlnaCBzY2hvb2wgc3R1ZGVudHMuIFdlIHdpbGwgZXhwbG9yZSBob3cgdGhlc2UgbGVhcm5pbmcgbW9kYWxpdGllcyBhbmQgc3R5bGVzIGFmZmVjdCBtYXRoIGFueGlldHkgYW1vbmcgY29sbGVnZSBzdHVkZW50cy4NCg0KKipPYmplY3RpdmUgNioqOiBDcmVhdGluZyBhbmQgdXNpbmcgY2FtcHVzIGxlYXJuaW5nIHJlc291cmNlcyBjYW4gcmVkdWNlIG1hdGggYW54aWV0eSBhbmQgaW1wcm92ZSB0aGVpciBhY2FkZW1pYyBwZXJmb3JtYW5jZSAoTW9saW5lciAmIEFsZWdyZSwgMjAyMCkuIFdlIHdpbGwgZXhwbG9yZSB3aGV0aGVyIGFuZCBob3cgbGVhcm5pbmcgcmVzb3VyY2VzIG9uIGNvbGxlZ2UgY2FtcHVzZXMgcmVkdWNlIGFueGlldHkuDQoNCg0KDQojIE1hdGVyaWFscw0KDQojIyBQYXJ0aWNpcGFudHMNCg0KVGhlIHN1cnZleSB3YXMgYXBwcm92ZWQgYnkgV0NVJ3MgSVJCLiBXZSBpbnZpdGUgYWxsIFdDVSBzdHVkZW50cyB3aG8gdGFrZSB0aGVpciBmaXJzdCBXQ1UgbWF0aGVtYXRpY3MgYW5kIHN0YXRpc3RpY3MgY2xhc3MgaW4gdGhlIGZhbGwgc2VtZXN0ZXJzIG9mIDIwMjQgYW5kIHRoZSBzcHJpbmcgc2VtZXN0ZXIgb2YgMjAyNS4gUGFydGljaXBhdGlvbiBpbiB0aGUgc3R1ZHkgYXJlIHZvbHVudGFyeSBhbmQgcmVzcG9uc2VzIHJlbWFpbiBhbm9ueW1vdXMuIFRoZSBkYXRhIHdhcyBjb2xsZWN0ZWQgaW4gdGhlIHNwcmluZyBhbmQgZmFsbCBzZW1lc3RlcnMgb2YgMjAyNCBiYXNlZCBvbiB0aGUgcHJvdG9jb2xzIHNldCBieSBXQ1XigJlzIEluc3RpdHV0aW9uYWwgUmVzZWFyY2guIFZpYSBRdWFsdHJpY3MsIHdlIHNlbnQgYW4gaW52aXRhdGlvbiBlbWFpbCB0byBhbGwgcXVhbGlmaWVkIHN0dWRlbnRzIHNwcmluZyBhbmQgZmFsbCBtaWQtc2VtZXN0ZXIuIEEgcmVtaW5kZXIgZW1haWwgd2FzIHNlbnQgYXQgdGhlIGVuZCBvZiB0aGUgc2VtZXN0ZXIgdG8gbm9uLXJlc3BvbmRpbmcgc3R1ZGVudHMgdG8gYm9vc3QgdGhlIHBhcnRpY2lwYXRpb24gcmF0ZS4gQSAkMTAgQW1hem9uIGdpZnQgY2FyZCB3YXMgb2ZmZXJlZCB0byBzdXJ2ZXkgY29tcGxldGVycyBhbmQgZGlzdHJpYnV0ZWQgdGhyb3VnaCBRdWFsdHJpY3Mgc28gYW5vbnltaXR5IGlzIGd1YXJhbnRlZWQuDQoNClRoZSBzdHVkeSBwb3B1bGF0aW9uIGluIHRoaXMgc3R1ZHkgaXMgZGVmaW5lZCBhcyBXQ1Ugc3R1ZGVudHMgYWdlZCAxOCB5ZWFycyBvciBvbGRlciB3aG8gdG9vayB0aGVpciBmaXJzdCBNQVQgY2xhc3MgYXQgV0NVLiBUaGUgcmVzdWx0cyBpbiB0aGlzIHN0dWR5IGNhbiBiZSBnZW5lcmFsaXplZCB0byBzaW1pbGFyIHJlZ2lvbmFsIHVuaXZlcnNpdGllcyBhbmQgdGhvc2UgcmVjZW50bHkgcmVjbGFzc2lmaWVkIFIyIGluc3RpdHV0aW9ucy4NCg0KIyMgU3VydmV5IEluc3RydW1lbnRzDQoNClRoZSBzdXJ2ZXkgd2lsbCBoYXZlIHRocmVlIGNvbXBvbmVudHM6DQoNCjEuCSoqTXVsdGktaXRlbSBTdXJ2ZXkgSW5zdHJ1bWVudCBNYXRoIEFueGlldHkqKjogQU1BUy4gV2Ugd2lsbCB1c2UgdGhlIGZyZXF1ZW50bHkgdXNlZCBBTUFTIHdpdGggbmluZSBpdGVtcyBjb250cmlidXRpbmcgdG8gdHdvIHNjYWxlczogTWF0aCBMZWFybmluZyBhbmQgTWF0aCBUZXN0aW5nLiBBTUFTIG9yaWdpbmF0ZXMgZnJvbSBhIHJlYW5hbHlzaXMgb2YgYSBNQVJTLVIgYnkgSG9wa28gZXQgYWwuICgyMDAzKS4gQU1BUyBpcyBzaG9ydCAoY29tcGxldGlvbiB0YWtlcyBhYm91dCA1IG1pbnV0ZXMpIGFuZCBoYXMgZ29vZCBwc3ljaG9tZXRyaWMgcHJvcGVydGllczogaGlnaCByZWxpYWJpbGl0eSBhcyBtZWFzdXJlZCBieSBpbnRlcm5hbCBjb25zaXN0ZW5jeSBhbmQgdGVzdC1yZXRlc3QgbWV0aG9kLCBjb25zdHJ1Y3QgdmFsaWRpdHkgYXMgbWVhc3VyZWQgYnkgZXhwbG9yYXRvcnkgYW5kIGNvbmZpcm1hdG9yeSBmYWN0b3IgYW5hbHlzZXMsIGFuZCBjb252ZXJnZW50IGFuZCBkaXNjcmltaW5hbnQgdmFsaWRpdHkuIChOdW1lcm91cyBzdWJzZXF1ZW50IHN0dWRpZXMgaGF2ZSBjb25maXJtZWQgdGhlc2UgcmVzdWx0cy4pIFdlIHdpbGwgdXNlIEFNQVMgdG8gbWVhc3VyZSBtYXRoIGFueGlldHkgaW4gdGhpcyBwcm9qZWN0Lg0KDQoyLgkqKk11bHRpLWl0ZW0gU3VydmV5IEluc3RydW1lbnQgZm9yIE1hdGggU2VsZi1lZmZpY2FjeSoqLiBNYXRoIGFueGlldHkgYW5kIG1hdGggc2VsZi1lZmZpY2FjeSBhcmUgbmVnYXRpdmVseSBjb3JyZWxhdGVkLiBUaGUgdGhyZWUtaXRlbSBzaG9ydCB2ZXJzaW9uIG9mIG1hdGggc2VsZi1lZmZpY2FjeSBxdWVzdGlvbm5haXJlczogKDEpIEkgdXN1YWxseSB1bmRlcnN0YW5kIGEgbWF0aGVtYXRpY2FsIGlkZWEgcXVpY2tseTsgKDIpIEkgaGF2ZSB0byB3b3JrIHZlcnkgaGFyZCB0byB1bmRlcnN0YW5kIG1hdGhlbWF0aWNzOyAoMykgSSBjYW4gY29ubmVjdCBtYXRoZW1hdGljYWwgaWRlYXMgdGhhdCBJIGhhdmUgbGVhcm5lZDsgdXNlZCBieSBSb3pnb25qdWsgZXQgYWwuICgyMDIwKS4NCg0KMy4gKipNdWx0aS1pdGVtIFN1cnZleSBJbnN0cnVtZW50IGZvciBTdHVkZW50J3MgUGVyY2VwdGlvbiBvbiBGYWN1bHR5IFRlYWNoaW5nIFN0cmF0ZWdpZXMqKjogU3R1ZGVudHMnIG1hdGhlbWF0aWNzIGFueGlldHkgaXMgZGlyZWN0bHkgaW5mbHVlbmNlZCBieSB0aGVpciBpbnN0cnVjdG9ycycgdGVhY2hpbmcgc3RyYXRlZ2llcy4gVGhpcyBzdHVkeSBlbXBsb3lzIHRoZSBUZWFjaGluZyBTdHJhdGVnaWVzIEludmVudG9yeSB1c2VkIGJ5IENhcmRpbm8gSnIuIGFuZCBPcnRlZ2EtRGVsYSBDcnV6ICgyMDIwKSB0byBhc3Nlc3Mgc3R1ZGVudHMnIHBlcmNlcHRpb25zIG9mIHRoZXNlIHN0cmF0ZWdpZXMuIFRoZSBpbnZlbnRvcnkgY29tcHJpc2VzIGVpZ2h0IGRpc3RpbmN0IGRpbWVuc2lvbnMgKHN1YnNjYWxlcykuDQoNCg0KNC4gKipNdWx0aS1pdGVtIFN1cnZleSBJbnN0cnVtZW50IGZvciBTdHVkZW50IExlYXJuaW5nIE1vZGFsaXRpZXMqKjogQVZJRCAoQWR2YW5jZW1lbnQgVmlhIEluZGl2aWR1YWwgRGV0ZXJtaW5hdGlvbikgaXMgYSBwcm9ncmFtIGludHJvZHVjZWQgYnkgTWVhZG93bGFyayBFbGVtZW50YXJ5IFNjaG9vbCB0aGF0IGFpbXMgdG8gY2xvc2UgdGhlIGFjaGlldmVtZW50IGdhcCBieSBwcmVwYXJpbmcgYWxsIHN0dWRlbnRzIGZvciBjb2xsZWdlIHJlYWRpbmVzcyBhbmQgc3VjY2VzcyBpbiBhIGdsb2JhbCBzb2NpZXR5LiBXZSB1c2VkIEFWSUQncyBTdHVkZW50IExlYXJuaW5nIE1vZGFsaXR5IEludmVudG9yeSB0byBpZGVudGlmeSBzdHVkZW50IGxlYXJuaW5nIHN0eWxlcyAoYXVkaXRvcnksIHZpc3VhbCwgYW5kIGtpbmVzdGhldGljKSBpbiB0aGlzIHN0dWR5LiBUaGUgaW52ZW50b3J5IGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9wZW5nZHNjaS5naXRodWIuaW8vTWF0aEFueGlldHkvQVZJRF9MZWFybmluZ19TdHlsZV9JbnZlbnRvcnkucGRmPi4NCg0KDQo1LiAqKk11bHRpLWl0ZW0gU3VydmV5IEluc3RydW1lbnQgZm9yIFN0dWRlbnQncyBFbmdhZ2VtZW50Kio6IFdlIHNlbGVjdCAxMiBxdWVzdGlvbm5haXJlcyBmcm9tIHRoZSBOU1NFIChOYXRpb25hbCBTdXJ2ZXkgb2YgU3R1ZGVudCBFbmdhZ2VtZW50KSB0byBhc3Nlc3Mgc3R1ZGVudHMgaW4tY2xhc3MgYW5kIGFmdGVyLWNsYXNzIGVuZ2FnZW1lbnQgYW5kIHVzZSBvZiBsZWFybmluZyByZXNvdXJjZXMuIFRoZSBUaGUgY29yZSBOU1NFIHN1cnZleSBmb3IgYSBmaXJzdC15ZWFyIG9yIHNlbmlvciBzdHVkZW50IGNvbnNpc3RzIG9mIGFwcHJveGltYXRlbHkgNDAgdG8gNTAgcmVxdWlyZWQgaXRlbXMsIGJ1dCB0aGUgdG90YWwgYmFuayBvZiBwb3RlbnRpYWwgcXVlc3Rpb25zIGlzIG11Y2ggbGFyZ2VyLiBUaGUgY29tcGxldCBpbnN0cnVtZW50IGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9uc3NlLmluZGlhbmEuZWR1L25zc2Uvc3VydmV5LWluc3RydW1lbnRzL3VzLWVuZ2xpc2guaHRtbD4uDQoNCjYuCSoqU2luZ2xlLWl0ZW0gcXVlc3Rpb25zKio6IFRoZXNlIHF1ZXN0aW9ucyBjYXB0dXJlIGRlbW9ncmFwaGljIGluZm9ybWF0aW9uLg0KDQoNCiMgUmF3IERhdGEgUHJvY2Vzc2luZw0KDQpBdCB0aGUgZW5kIG9mIGRhdGEgY29sbGVjdGlvbiwgd2UgcmVjZWl2ZWQgODk1IHJlc3BvbnNlcy4gT2YgdGhlc2UsIDE5OSBwYXJ0aWNpcGFudHMgZGlkIG5vdCBjb21wbGV0ZSB0aGUgbWFpbiBzdXJ2ZXkgc3Vic2NhbGVzLiBUaGUgYW5hbHlzaXMgaXMgYmFzZWQgb24gdGhlIHJlbWFpbmluZyA2OTYgcmVzcG9uc2VzIGZvciB3aGljaCB0aGUgbWFpbiBzdWJzY2FsZXMgd2VyZSBjb21wbGV0ZWQsIHdoaWNoIGNvbnRhaW5lZCBvbmx5IGEgZmV3IG1pc3NpbmcgdmFsdWVzLiBTZXZlcmFsIHJlZHVuZGFudCB2YXJpYWJsZXMgd2VyZSByZW1vdmVkIGZyb20gdGhlIHJhdyBkYXRhLiBJbiBhZGRpdGlvbiwgc29tZSBvcmlnaW5hbCBjYXRlZ29yaWNhbCB2YXJpYWJsZXMgd2VyZSByZWNhdGVnb3JpemVkIHRvIGF2b2lkIHNwYXJzZSBncm91cHMgYW5kIGltcHJvdmUgaW50ZXJwcmV0YWJpbGl0eS4NCg0KYGBge3IgZWNobyA9IEZBTFNFLCBldmFsID0gVFJVRX0NCldvcmtpbmdEYXRhIDwtIHJlYWQuY3N2KCJDOlxcVXNlcnNcXDc1Q1BFTkdcXE9uZURyaXZlIC0gV2VzdCBDaGVzdGVyIFVuaXZlcnNpdHkgb2YgUEFcXERlc2t0b3BcXGNwZW5nXFxXQ1UtVGVhY2hpbmdcXDIwMjVGYWxsXFxNYXRoQXhpZXR5XFxXb3JraW5nRGF0YVNldE5vTWlzc2luZ3MwMi5jc3YiKQ0KV29ya2luZ0RhdGEkSUQgPC0gMTpkaW0oV29ya2luZ0RhdGEpWzFdDQojIERlbW9ncmFwaGljcw0KRGVtb2dyYXBoaWNzIDwtIFdvcmtpbmdEYXRhWywgYygiSUQiLCAiU2V4IiwgIkdlbmRlciIsICJDbGFzcyIsICJNYWpvciIsICJFdGhuaWNpdHkiLCAiQ291cnNlMiIpXQ0KIyBNYXRoIEFueGlldHkNCkFueGlldHkgPC0gV29ya2luZ0RhdGFbLCBjKCJJRCIsICJBTUFTLjEiLCAiQU1BUy4yIiwgIkFNQVMuMyIsICJBTUFTLjQiLCAiQU1BUy41IiwgIkFNQVMuNiIsICJBTUFTLjciLCAiQU1BUy44IiwgIkFNQVMuOSIpXQ0KIyBTZWxmLWVmZmljYWN5DQpTZWxmRWZmaWNhY3kgPC0gV29ya2luZ0RhdGFbLCBjKCJJRCIsICAiTVNFUy4xIiwgIk1TRVMuMiIsICJNU0VTLjMiICldDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMgICBUZWFjaGluZyBTdHJhdGVnaWVzDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMjIENvb3BlcmF0aXZlDQpDb29wb3JhdGl2ZSA8LSBXb3JraW5nRGF0YVssIGMoIklEIiwgICJTLkNBLjEiLCAiUy5DQS4yIiwgIlMuQ0EuMyIsICJTLkNBLjQiLCAiUy5DQS41IiwgIlMuQ0EuNiIpXQ0KIyMgTGVjdHVyZSBUeXBlDQpMZWN0dXJlVHlwZSA8LSBXb3JraW5nRGF0YVssIGMoIklEIiwgICJTLkxULjEiLCAiUy5MVC4yIiwgIlMuTFQuMyIsICAiUy5MVC40IiwgICJTLkxULjUiLCAiUy5MVC42IiwgIlMuTFQuNyIpXQ0KIyMgRGVkdWN0aXZlIEFwcHJvYWNoDQpEZWR1Y3RpdmUgPC0gV29ya2luZ0RhdGFbLCBjKCJJRCIsICAiUy5EQS4xIiAsICJTLkRBLjIiLCAiUy5EQS4zIiwgIlMuREEuNCIsICJTLkRBLjUiLCAiUy5EQS42IiwgIlMuREEuNyIpXQ0KIyMgSW5kdWN0aXZlIEFwcHJvYWNoDQpJbmR1Y3RpdmUgPC0gV29ya2luZ0RhdGFbLCBjKCJJRCIsICJTLklBLjEiLCAiUy5JQS4yIiwgICJTLklBLjMiLCAgIlMuSUEuNCIsICJTLklBLjUiLCJTLklBLjYiLCAiUy5JQS43IildDQojIyBEZW1vbnN0cmF0aW9uDQpEZW1vbnN0cmF0aW9uIDwtV29ya2luZ0RhdGFbLCBjKCJJRCIsICJTLkQuMSIsICJTLkQuMiIsICJTLkQuMyIsICJTLkQuNCIsICJTLkQuNSIsICAiUy5ELjYiLCAiUy5ELjciKV0NCiMjIFJlcGV0aXRpdmUgRXhlcmNpc2VzDQpSZXBldGl0aXZlIDwtIFdvcmtpbmdEYXRhWywgYygiSUQiLCAiUy5SRS4xIiwgICJTLlJFLjIiLCAiUy5SRS4zIiwgIlMuUkUuNCIsICJTLlJFLjUiLCAiUy5SRS42IiwgIlMuUkUuNyIpXQ0KIyMgSW50ZWdyYXRpdmUgQXBwcm9hY2gNCkludGVncmF0aXZlIDwtIFdvcmtpbmdEYXRhWywgYygiSUQiLCAiUy5JQS4xLjEiLCAiUy5JQS4yLjEiLCAiUy5JQS4zLjEiLCAiUy5JQS40LjEiLCAiUy5JQS41LjEiLCAiUy5JQS42LjEiLCAiUy5JQS43LjEiKV0NCiMgVXNpbmcgVGVjaG5vbG9neTogZHJvcCBUMSBhbmQgVDcNClRlY2hub2xvZ3kgPC0gV29ya2luZ0RhdGFbLCBjKCJJRCIsICJULjIiLCAiVC4zIiwgIlQuNCIsICJULjUiLCAiVC42IiwgIlQuOCIsICJULjkiLCAiVC4xMCIsICJULjExIiwiVC4xMiIpXQ0KIyBMZWFybmluZyBNb2RhbGl0aWVzDQpNb2RhbGl0eSA8LSBXb3JraW5nRGF0YVssIGMoIklEIiwgICJNUy4xIiwgIk1TLjIiLCAiTVMuMyIsICJNUy40IiwgIk1TLjUiLCAiTVMuNiIsICJNUy43IiwgIk1TLjgiLCAiTVMuOSIsICJNUy4xMCIsICJNUy4xMSIsICJNUy4xMiIpXQ0KIyBFbmdhZ2VtZW50OiBrZWVwIG9ubHkgZmlyc3QgdGhyZWUgaXRlbXMNCkVuZ2FnZSA8LSBXb3JraW5nRGF0YVssIGMoIklEIiwgICJDUi4xIiwgIkNSLjIiLCAiQ1IuMyIpXQ0KIyBSZXNvdXJjZXMNClJlc291cmNlIDwtIFdvcmtpbmdEYXRhWywgYygiSUQiLCAiQ1IuOSIsICJDUi4xMCIsICJDUi4xMSIsICJDUi4xMiIpXQ0KYGBgDQoNCg0KDQojIyBNaXNzaW5nIFZhbHVlIEltcHV0YXRpb24NCg0KVG8gbWFpbiB0aGlzIHNhbXBsZSBzaXplLCB3ZSB1c2UgcmFuZG9tIGltcHV0YXRpb24gYXBwcm9hY2ggdG8gZmlsbCBpbiB0aGUgbWlzc2luZyB2YWx1ZXMuIFNpbmNlIGFsbCBtdWx0aS1pdGVtIHN1Yi1zY2FsZXMgd2VyZSBtZWFzdXJlZCB1c2luZyBhIExpa2VydCBzY2FsZSwgdGhlIHNjb3JlcyBmb2xsb3dzIGEgbXVsdGlub21pYWwgZGlzdHJpYnV0aW9uLiBUaGUgZW1waXJpY2FsIGRpc3RyaWJ1dGlvbiB3aWxsIGJlIHVzZWQgaW4gdGhlIHJhbmRvbSBpbXB1dGF0aW9uIHRvIG1haW4gdGhlIHByb2JhYmlsaXR5IGRpc3RyaWJ1dGlvbiBvZiB0aGUgb2JzZXJ2ZWQgZGF0YS4gVGhlIGZvbGxvd2luZyBjb2RlIGltcHV0ZXMgdGhlIG1pc3NpbmcgdmFsdWVzIGluIGFsbCBtdWx0aS1pdGVtIHN1YnNjYWxlcy4NCg0KYGBge3IsIGV2YWwgPSBUUlVFfQ0KSW1wdXRhdGlvbiA9IGZ1bmN0aW9uKERhdGFOYW1lKXsNCiAgZm9yIChpIGluIDE6KGRpbShEYXRhTmFtZSlbMl0pKXsNCiAgICB2ZWMgPSBhcy52ZWN0b3IoRGF0YU5hbWVbLCBpXSkNCiAgICBuYS5pZCA9IHdoaWNoKGlzLm5hKHZlYykpDQogICAgbjAgPSBsZW5ndGgobmEuaWQpDQogICAgcHJvYjAgPSB0YWJsZSh2ZWMpL2xlbmd0aCh2ZWMpDQogICAgaW1wdXQudmFsID0gTlVMTA0KICAgICAgZm9yIChqIGluIDE6bjApew0KICAgICAgaW1wdXQudmFsW2pdID0gc2FtcGxlKDE6bGVuZ3RoKHByb2IwKSwgc2l6ZSA9IDEsIHByb2IgPSBwcm9iMCkNCiAgICB9DQogICAgRGF0YU5hbWVbbmEuaWQsIGldID0gaW1wdXQudmFsDQogIH0NCiAgIERhdGFOYW1lDQp9DQpgYGANCg0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGV2YWwgPSBUUlVFfQ0KQ29tcC5BbnhpZXR5ID0gSW1wdXRhdGlvbihBbnhpZXR5KQ0KQ29tcC5TZWxmRWZmaWNhY3kwID0gSW1wdXRhdGlvbihTZWxmRWZmaWNhY3kpDQojIHJldmVyc2UgY29kaW5nIGluIFNlbGYtRWZmaWNhY3kNCkNvbXAuU2VsZkVmZmljYWN5ID0gQ29tcC5TZWxmRWZmaWNhY3kwDQpDb21wLlNlbGZFZmZpY2FjeSRNU0VTLjEgPTYtIENvbXAuU2VsZkVmZmljYWN5MCRNU0VTLjENCkNvbXAuU2VsZkVmZmljYWN5JE1TRVMuMyA9Ni0gQ29tcC5TZWxmRWZmaWNhY3kwJE1TRVMuMw0KIyMNCkNvbXAuQ29vcG9yYXRpdmUgPSBJbXB1dGF0aW9uKENvb3BvcmF0aXZlKQ0KQ29tcC5MZWN0dXJlVHlwZSA9IEltcHV0YXRpb24oTGVjdHVyZVR5cGUpDQpDb21wLkRlZHVjdGl2ZSA9IEltcHV0YXRpb24oRGVkdWN0aXZlKQ0KQ29tcC5JbmR1Y3RpdmUgPSBJbXB1dGF0aW9uKEluZHVjdGl2ZSkNCkNvbXAuRGVtb25zdHJhdGlvbiA9IEltcHV0YXRpb24oRGVtb25zdHJhdGlvbikNCkNvbXAuUmVwZXRpdGl2ZSA9IEltcHV0YXRpb24oUmVwZXRpdGl2ZSkNCkNvbXAuSW50ZWdyYXRpdmUgPSBJbXB1dGF0aW9uKEludGVncmF0aXZlKQ0KIyMgcmV2ZXJzZSBjb2RpbmcgaW4gNSBhbmQgNyBpbiBUZWNobm9sb2d5DQpDb21wLlRlY2hub2xvZ3kwID0gSW1wdXRhdGlvbihUZWNobm9sb2d5KQ0KQ29tcC5UZWNobm9sb2d5MSA9IENvbXAuVGVjaG5vbG9neTANCkNvbXAuVGVjaG5vbG9neTEkVC41ID02LSBDb21wLlRlY2hub2xvZ3kwJFQuNQ0KIyMNCkNvbXAuVGVjaG5vbG9neSA9IDYgLSBDb21wLlRlY2hub2xvZ3kxDQojIw0KQ29tcC5FbmdhZ2UgPSA1LUltcHV0YXRpb24oRW5nYWdlKQ0KQ29tcC5SZXNvdXJjZSA9IDUtSW1wdXRhdGlvbihSZXNvdXJjZSkNCiMjIE1vZGFsaXR5DQpDb21wLk1vZGFsaXR5ID0gSW1wdXRhdGlvbihNb2RhbGl0eSkNCmBgYA0KDQoNCiMjIFJldmVyc2UgU2NvcmluZw0KDQoqKlJldmVyc2Ugc2NvcmluZyoqIGlzIGEgY3J1Y2lhbCBkYXRhIHByZXBhcmF0aW9uIHN0ZXAgZm9yIG11bHRpLWl0ZW0gc3VydmV5cyB3aGVyZSBzb21lIGl0ZW1zIGFyZSB3b3JkZWQgaW4gdGhlIG9wcG9zaXRlIGRpcmVjdGlvbiB0byBwcmV2ZW50IHJlc3BvbnNlIGJpYXMuIEFmdGVyIGl0ZW0td2lzZSByZXZpZXcgb2YgYWxsIGluc3RydW1lbnRzIGFsb25nIHdpdGggc3RhdGlzdGljYWwgcHJvY2VkdXJlcyBvZiBjb3JyZWxhdGlvbiBhbmQgY29uZmlybWF0b3J5IGZhY3RvciBhbmFseXNpcyAoQ0ZBKSwgaXRlbSAyIGluIHRoZSAqU2VsZi1lZmZpY2FjeSBJbnN0cnVtZW50KiBhbmQgKiphbGwgcXVlc3Rpb25zKiogZXhjZXB0IGl0ZW1zIDUgYW5kIDcgaW4gdGhlICpUZWNobm9sb2d5IEluc3RydW1lbnQqIHdlcmUgbmVnYXRpdmVseSB3b3JkZWQuIFRoZSBzY29yZXMgb2YgdGhlc2UgaXRlbXMgd2VyZSByZXZlcnNlZC4NCg0KSW4gYWRkaXRpb24sIGFsbCBxdWVzdGlvbnMgcmVnYXJkaW5nIGVuZ2FnZW1lbnQgYW5kIHJlc291cmNlIHVzZSB3ZXJlIHJldmVyc2Utd29yZGVkLCBzbyB0aGVpciBzY29yZXMgd2VyZSByZXZlcnNlZCBmb3IgdGhlIHN1YnNlcXVlbnQgYW5hbHlzaXMuDQoNCg0KIyMgU3BhcnNlIENhdGVnb3J5IFJlZ3JvdXBpbmcNCg0KVHdvIHZhcmlhYmxlcyBuZWVkIHRvIGJlIHJlZ3JvdXBlZCBpbiB0aGUgZm9sbG93aW5nOiBjb3Vyc2UgbGV2ZWwgYW5kIGV0aG5pY2l0eS4NCg0KKiAqKk1hdGhDb3Vyc2VMZXZlbCoqDQogICsgKk1hdGguSSo6IE1BVFEzMCwgTUFUMTAwLCBNQVQxMDEsIE1BVDEwMiwNCiAgKyAqTWF0aC5JSSo6IE1BVDE5MywgTUFUMTA0LCBNQVQxMTIsIE1BVDExMywgTUFUMTE1LCBNQVQxMzENCiAgKyAqTWF0aC5JSUkqOiBNQVQxNDMsIE1BVDE0NSwgTUFUMTUxLCBNQVQxNjENCiAgKyAqTWF0aC5JVio6IE1BVDE2Mi1NQVQ0ODANCiAgKyAqU3RhdHMqOiBNQVQxMjEsIE1BVDEyNSwgU1RBMjAwDQogICsgKk90aGVyKjogQWxsIGNvdXJzZXMgbm90IGxpc3RlZCBhYm92ZQ0KDQoqICoqRXRobmljaXR5KioNCiAgKyAqV2hpdGUqDQogICsgKkJsYWNrKjogQmxhY2sgYW5kIEFmcmljYW4gQW1lcmljYW4NCiAgKyAqQXNpYW4qDQogICsgKk90aGVyKjogTmF0aXZlIEhhd2FpaWFuIG9yIFBhY2lmaWMgSXNsYW5kZXIsIE11bHRpcGxlIEV0aG5pY2l0eSBvciBPdGhlciwgUHJlZmVyIE5vdCBUbyBBbnN3ZXINCg0KKiAqKkxlYXJuaW5nIE1vZGFsaXRpZXMqKg0KDQpgYGB7cn0NCmRmX3dpdGhfZnJlcSA8LSBDb21wLk1vZGFsaXR5ICU+JQ0KICByb3d3aXNlKCkgJT4lDQogIG11dGF0ZSgNCiAgICBmcmVxX0EgPSBzdW0oY19hY3Jvc3MoTVMuMTpNUy4xMikgPT0gIjEiKSwNCiAgICBmcmVxX0IgPSBzdW0oY19hY3Jvc3MoTVMuMTpNUy4xMikgPT0gIjIiKSwNCiAgICBmcmVxX0MgPSBzdW0oY19hY3Jvc3MoTVMuMTpNUy4xMikgPT0gIjMiKQ0KICApICU+JQ0KICB1bmdyb3VwKCkNCiMjIw0KZGZfd2l0aF9mcmVxJG1heF9mcmVxX2NvbCA8LSBuYW1lcyhkZl93aXRoX2ZyZXEpW21heC5jb2woZGZfd2l0aF9mcmVxWywgYygiZnJlcV9BIiwgImZyZXFfQiIsICJmcmVxX0MiKV0pICsgMV0NCmRmX3dpdGhfZnJlcSRtYXhfZnJlcV92YWx1ZSA8LSBhcHBseShkZl93aXRoX2ZyZXFbLCBjKCJmcmVxX0EiLCAiZnJlcV9CIiwgImZyZXFfQyIpXSwgMSwgbWF4KQ0KZGZfd2l0aF9mcmVxJG1vZGFsaXR5IDwtIGlmZWxzZShkZl93aXRoX2ZyZXEkbWF4X2ZyZXFfY29sPT0iTVMuMSIsICJBdWRpdG9yeSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoZGZfd2l0aF9mcmVxJG1heF9mcmVxX2NvbD09Ik1TLjIiLCAiVmlzdWFsIiwgIktpbmVzdGhldGljIikpDQoNCmBgYA0KDQoNCg0KDQpgYGB7ciwgZWNobyA9IEZBTFNFLCBldmFsID0gVFJVRX0NCkRlbW9ncmFwaGljcyRtYXRoLmxldmVsID0gaWZlbHNlKERlbW9ncmFwaGljcyRDb3Vyc2UyICVpbiUgYygxLCAyLCAzLCA0KSwgIm1hdGgwMSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKERlbW9ncmFwaGljcyRDb3Vyc2UyICVpbiUgYyg1LCA2LCA3LCA4LCA5LCAxMiksICJtYXRoMDIiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoRGVtb2dyYXBoaWNzJENvdXJzZTIgJWluJSBjKDEzLCAxNCwgMTUsIDE2KSwgIm1hdGgwMyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoRGVtb2dyYXBoaWNzJENvdXJzZTIgJWluJSBjKDEwLCAxMSwgMzYsIDM3LCAzOCwgMzksIDQwLCA0MSwgNDIpLCAic3RhdHMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKERlbW9ncmFwaGljcyRDb3Vyc2UyICVpbiUgYyg0MywgNDQpLCAib3RoZXIiLCAibWF0aDA0IikpKSkpIA0KRGVtb2dyYXBoaWNzJHJhY2UgPSBpZmVsc2UoRGVtb2dyYXBoaWNzJEV0aG5pY2l0eSA9PSAxLCAid2hpdGUiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShEZW1vZ3JhcGhpY3MkRXRobmljaXR5ID09IDIsICJCbGFjayIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShEZW1vZ3JhcGhpY3MkRXRobmljaXR5ID09IDQsICJBc2lhbiIsICJvdGhlciIpKSkNCkRlbW9ncmFwaGljcyRzZXggPSBpZmVsc2UoRGVtb2dyYXBoaWNzJFNleCA9PSAxLCAiZmVtYWxlIiwgIm1hbGUiKQ0KRGVtb2dyYXBoaWNzJG1ham9yID0gaWZlbHNlKERlbW9ncmFwaGljcyRNYWpvciA9PSAxLCAiU1RFTSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShEZW1vZ3JhcGhpY3MkTWFqb3IgPT0gMiwgIkJ1c2luZXNzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKERlbW9ncmFwaGljcyRNYWpvciA9PSAzLCAiSGVhbHRoIiwgIk90aGVyIikpKQ0KRGVtb2dyYXBoaWNzJGNsYXNzID0gaWZlbHNlKERlbW9ncmFwaGljcyRDbGFzcyA9PSAxLCAieXIxIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKERlbW9ncmFwaGljcyRDbGFzcyA9PSAyLCAieXIyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKERlbW9ncmFwaGljcyRDbGFzcyA9PSAzLCAieXIzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoRGVtb2dyYXBoaWNzJE1ham9yID09IDQsICJ5cjQiLCAieXI1KyIpKSkpDQpEZW1vZ3JhcGhpY3MkbW9kYWxpdHkgPC0gZGZfd2l0aF9mcmVxJG1vZGFsaXR5DQoNCmRlbW9ncmFwaGljcyA9IERlbW9ncmFwaGljc1ssIGMoIklEIiwgInNleCIsICJyYWNlIiwgImNsYXNzIiwgIm1ham9yIiwgIm1hdGgubGV2ZWwiLCAibW9kYWxpdHkiKV0NCmBgYA0KDQoNCiMjIEV4cGxvcmF0b3J5IEZhY3RvciBBbmFseXNpcyAoRUZBKSBvbiBBbnhpZXR5DQoNClRoZSBhYmJyZXZpYXRlZCBtYXRoZW1hdGljYWwgYW54aWV0eSAoTUEpIGluc3RydW1lbnQgZGV2ZWxvcGVkIGJ5IEhvcGtvIGV0IGFsLiAoMjAwMykgaXMgY2hhcmFjdGVyaXplZCBieSBhIHR3by1mYWN0b3Igc3RydWN0dXJlIHRoYXQgZGl2aWRlcyBpbnRvIHR3byBzdWJzY2FsZXM6IG1hdGhlbWF0aWNzIGV2YWx1YXRpb24gYW54aWV0eSAoTUVBKSBhbmQgbWF0aGVtYXRpY3MgbGVhcm5pbmcgYW54aWV0eSAoTUxBKS4gVGhlIHN1YnNlcXVlbnQgZXhwbG9yYXRvcnkgZmFjdG9yIGFuYWx5c2lzIHNlcnZlcyB0byB2YWxpZGF0ZSB0aGlzIGNvbnN0cnVjdC4NCg0KDQpgYGB7ciByZXN1bHRzID0gRkFMU0V9DQojIENoZWNrIGNvcnJlbGF0aW9ucyAodmlzdWFsbHkpDQpuID0gZGltKENvbXAuQW54aWV0eVssLTFdKVsxXQ0KY29yX21hdHJpeCA8LSBjb3IoQ29tcC5BbnhpZXR5WywtMV0pDQojY29yUGxvdChjb3JfbWF0cml4LCB1cHBlciA9IEZBTFNFKQ0KIyBCYXJ0bGV0dCdzIFRlc3Qgb2YgU3BoZXJpY2l0eSAod2Ugd2FudCBhIHNpZ25pZmljYW50IHAtdmFsdWUsIHAgPCAuMDUpDQpjb3J0ZXN0LmJhcnRsZXR0KGNvcl9tYXRyaXgsIG4gPSBuKQ0KDQojIEtNTyBNZWFzdXJlIG9mIFNhbXBsaW5nIEFkZXF1YWN5IChNU0EpIChXZSB3YW50IG92ZXJhbGwgTVNBID4gMC42LCBpZGVhbGx5ID4gMC44KQ0KS01PKGNvcl9tYXRyaXgpDQpgYGANCg0KQmFydGxldHQncyB0ZXN0IG9mIHNwaGVyaWNpdHkgcHJvZHVjZWQgYSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IHJlc3VsdCAocCA8IC4wMDEpLCBjb25maXJtaW5nIHRoYXQgdGhlIHZhcmlhYmxlcyBhcmUgc3VmZmljaWVudGx5IGNvcnJlbGF0ZWQgdG8gcHJvY2VlZCB3aXRoIGZhY3RvciBhbmFseXNpcy4gVGhlIEthaXNlci1NZXllci1PbGtpbiAoS01PKSBNZWFzdXJlIG9mIFNhbXBsaW5nIEFkZXF1YWN5LCB3aXRoIGJvdGggb3ZlcmFsbCBhbmQgaXRlbS1sZXZlbCB2YWx1ZXMgZXhjZWVkaW5nIDAuODAsIGluZGljYXRlcyB0aGF0IHRoZSBkYXRhIGNvbnRhaW4gYWRlcXVhdGUgY29tbW9uIHZhcmlhbmNlIHRvIHdhcnJhbnQgZmFjdG9yIGFuYWx5c2lzLiBGdXJ0aGVybW9yZSwgdGhlIHNjcmVlIHBsb3QgY2xlYXJseSBkZW1vbnN0cmF0ZXMgdGhlIGFudGljaXBhdGVkIHR3by1mYWN0b3Igc3RydWN0dXJlIG9mIHRoZSBjb25zdHJ1Y3QuDQoNCg0KYGBge3J9DQoNCiMgR2V0IGVpZ2VudmFsdWVzDQpmYV9yZXN1bHQgPC0gZmEoQ29tcC5BbnhpZXR5WywtMV0sIG5mYWN0b3JzID0gbmNvbChDb21wLkFueGlldHlbLC0xXSksIHJvdGF0ZSA9ICJub25lIikNCmVpZ2VudmFsdWVzIDwtIGZhX3Jlc3VsdCRlLnZhbHVlcw0KDQojIFNjcmVlIHBsb3Qgd2l0aCBob3Jpem9udGFsIGxpbmUgdXNpbmcgc2hhcGVzDQpzY3JlZV9wbG90IDwtIHBsb3RfbHkoeCA9IDE6bGVuZ3RoKGVpZ2VudmFsdWVzKSwgeSA9IGVpZ2VudmFsdWVzLA0KICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSAnc2NhdHRlcicsIG1vZGUgPSAnbGluZXMrbWFya2VycycsDQogICAgICAgICAgICAgICAgICAgICAgbGluZSA9IGxpc3Qod2lkdGggPSAzKSwNCiAgICAgICAgICAgICAgICAgICAgICBtYXJrZXIgPSBsaXN0KHNpemUgPSA4KSkgJT4lDQogIGxheW91dCgNCiAgICB0aXRsZSA9ICJTY3JlZSBQbG90IHdpdGggS2Fpc2VyIENyaXRlcmlvbiAoRWlnZW52YWx1ZSkiLA0KICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICJGYWN0b3IgTnVtYmVyIiksDQogICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIkVpZ2VudmFsdWUiKSwNCiAgICBzaGFwZXMgPSBsaXN0KA0KICAgICAgbGlzdCgNCiAgICAgICAgdHlwZSA9ICJsaW5lIiwNCiAgICAgICAgeDAgPSAwLA0KICAgICAgICB4MSA9IGxlbmd0aChlaWdlbnZhbHVlcyksDQogICAgICAgIHkwID0gMSwNCiAgICAgICAgeTEgPSAxLA0KICAgICAgICBsaW5lID0gbGlzdChjb2xvciA9ICJyZWQiLCB3aWR0aCA9IDIsIGRhc2ggPSAiZGFzaCIpDQogICAgICApDQogICAgKSwNCiAgICBhbm5vdGF0aW9ucyA9IGxpc3QoDQogICAgICBsaXN0KA0KICAgICAgICB4ID0gbGVuZ3RoKGVpZ2VudmFsdWVzKSAqIDAuOCwNCiAgICAgICAgeSA9IDEuMSwNCiAgICAgICAgdGV4dCA9ICJLYWlzZXIgQ3JpdGVyaW9uICjOuyA9IDEpIiwNCiAgICAgICAgc2hvd2Fycm93ID0gRkFMU0UsDQogICAgICAgIGZvbnQgPSBsaXN0KGNvbG9yID0gInJlZCIpDQogICAgICApDQogICAgKSwNCiAgICAgbWFyZ2luID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgIHQgPSAxMDAsICAjIEFkanVzdCB0aGlzIHZhbHVlIHRvIGluY3JlYXNlIG9yIGRlY3JlYXNlIHRoZSB0b3AgbWFyZ2luDQogICAgICAgICAgICAgICAgICBiID0gNTAsDQogICAgICAgICAgICAgICAgICBsID0gNTAsDQogICAgICAgICAgICAgICAgICByID0gNTApDQogICkNCg0Kc2NyZWVfcGxvdA0KYGBgDQoNCk5leHQsIHdlIHBlcmZvcm0gRUZBIHRvIGlkZW50aWZ5IHRoZSBpdGVtcyBvZiBNRUEgYW5kIE1MQSB0aHJvdWdoIGZhY3RvciBsb2FkaW5ncy4gDQoNCmBgYHtyfQ0KIyMgdHdvLWZhY3RvciBhRUZBDQplZmFfMmZhY3RvciA8LSBmYShDb21wLkFueGlldHlbLC0xXSwgbmZhY3RvcnMgPSAyLCByb3RhdGUgPSAib2JsaW1pbiIsIA0KICAgICAgICAgICAgICAgICAgZm0gPSAicGEiLCBzY29yZXMgPSAicmVncmVzc2lvbiIpDQojIENyZWF0ZSBhIGNsZWFuIGxvYWRpbmdzIHRhYmxlDQpsb2FkaW5nc190YWJsZSA8LSBmYS5zb3J0KGVmYV8yZmFjdG9yJGxvYWRpbmdzW10pDQpwYW5kZXIobG9hZGluZ3NfdGFibGUsIGRpZ2l0cyA9IDIsIGN1dG9mZiA9IDAuMykNCmBgYA0KDQpBcyBzaG93biBpbiB0aGUgdGFibGUgYWJvdmUsIGl0ZW1zIDIsIDQsIDUsIGFuZCA4IGxvYWQgb250byB0aGUgZXZhbHVhdGlvbiBhbnhpZXR5IGZhY3Rvciwgd2hlcmVhcyB0aGUgcmVtYWluaW5nIGl0ZW1zIGxvYWQgb250byB0aGUgbGVhcm5pbmcgYW54aWV0eSBmYWN0b3IuIFR3byBkaXN0aW5jdCBzdWJzY2FsZXMgd2lsbCBiZSBlc3RhYmxpc2hlZCBmb3Igc3Vic2VxdWVudCBhbmFseXNlcy4NCg0KYGBge3J9DQpBbnhpZXR5Lm1lYSA8LSBDb21wLkFueGlldHlbLCBjKCJJRCIsICAiQU1BUy4yIiwgIkFNQVMuNCIsICJBTUFTLjUiLCAgIkFNQVMuOCIpXQ0KQW54aWV0eS5tbGEgPC0gQ29tcC5BbnhpZXR5WywgYygiSUQiLCAiQU1BUy4xIiwgIkFNQVMuMyIsICJBTUFTLjYiLCAiQU1BUy43IiwgIkFNQVMuOSIpXQ0KYGBgDQoNCg0KIyBWYWxpZGF0aW9uIGFuZCBSZWxpYWJpbGl0eQ0KDQpUaGUgbWFqb3IgbXVsdGktaXRlbSBpbnN0cnVtZW50cyB1c2VkIGluIHRoaXMgc3R1ZHkgYXJlIHdlbGwtZXN0YWJsaXNoZWQgYW5kIGhhdmUgYmVlbiB1c2VkIGluIHZhcmlvdXMgcHVibGlzaGVkIHJlc2VhcmNoLiBJbiBwcmFjdGljZSwgdGhlIHZhbGlkaXR5IGFuZCByZWxpYWJpbGl0eSBvZiBzdWNoIGVzdGFibGlzaGVkIGluc3RydW1lbnRzIG11c3QgYmUgY29uZmlybWVkIGJlZm9yZSBhbnkgc3RhdGlzdGljYWwgYW5hbHlzaXMuIFdlIG5leHQgcGVyZm9ybSByZWxpYWJpbGl0eSBhbmQgdmFsaWRpdHkgYW5hbHlzZXMgdG8gd2FycmFudCB0aGUgY3JlZGliaWxpdHkgb2YgdGhlIG92ZXJhbGwgc3VydmV5IGRlc2lnbiBhbmQgdGhlIHF1YWxpdHkgb2YgdGhlIGNvbGxlY3RlZCBkYXRhLg0KDQoNCiMjIFZhbGlkaXR5IEFuYWx5c2lzDQoNCioqVmFsaWRpdHkqKiBvZiBhIG11bHRpLWl0ZW0gc3VydmV5IGluc3RydW1lbnQgYW5zd2VycyB0aGUgcXVlc3Rpb246ICJBbSBJIGFjdHVhbGx5IG1lYXN1cmluZyB3aGF0IEkgaW50ZW5kIHRvIG1lYXN1cmU/IiBJdCdzIGFib3V0IHRoZSBzb3VuZG5lc3Mgb2YgdGhlIGludGVycHJldGF0aW9uIG9mIHRoZSBzY29yZXMuIEluIHBzeWNob21ldHJpY3MsICoqdmFsaWRpdHkqKiByZWZlcnMgdG8gdGhlIGRlZ3JlZSB0byB3aGljaCBhIHNjYWxlIG1lYXN1cmVzIHdoYXQgaXQgY2xhaW1zIHRvIG1lYXN1cmUuIEZvciBhIHNpbmdsZS1mYWN0b3IgaW5zdHJ1bWVudCwgdGhpcyBtZWFucyBhbGwgaXRlbXMgYXJlIGluZGljYXRvcnMgb2Ygb25lIHVuZGVybHlpbmcgY29uc3RydWN0IHN1Y2ggYXMgbWF0aHMgYW54aWV0eSwgc2VsZi1lZmZpY2FjeSwgZW5nYWdlbWVudCwgZXRjLiBpbiB0aGlzIGNvbXByZWhlbnNpdmUgc3VydmV5LiBUaGUgQ0ZBIGhhcyBiZWVuIHVzZWQgaW4gc3VydmV5IHJlc2VhcmNoIHdpZGVseSwgc2VlIFdhdHNvbiwgZXQgYWwgKDE5ODgpIGFuZCBNYXJzaCAoMTk5NikuIA0KDQoqKkNvbmZpcm1hdG9yeSBGYWN0b3IgQW5hbHlzaXMgKENGQSkqKiBpcyBhIHBvd2VyZnVsIHN0YXRpc3RpY2FsIHRlY2huaXF1ZSB1c2VkIHRvIHRlc3QgYSBwcmUtc3BlY2lmaWVkIHRoZW9yeSBhYm91dCB0aGUgc3RydWN0dXJlIG9mIHlvdXIgaW5zdHJ1bWVudC4gV2UgdXNlIENGQSB0byBjb25maXJtIHRoYXQgeW91ciBoeXBvdGhlc2l6ZWQgc2luZ2xlLWZhY3RvciBtb2RlbCBpcyBjb25zaXN0ZW50IHdpdGggdGhlIG9ic2VydmVkIGRhdGEuIEl0IHByb3ZpZGVzIHJpZ29yb3VzIGV2aWRlbmNlIGZvciBjb25zdHJ1Y3QgdmFsaWRpdHkgaW4gYSBsaXN0IG9mIGNvbnZlbnRpb25hbCBtZWFzdXJlczoNCg0KKiAqKkZhY3RvciBMb2FkaW5ncyoqIGFyZSB0aGUgc3RhbmRhcmRpemVkIHdlaWdodHMgZnJvbSB0aGUgQ29uZmlybWF0b3J5IEZhY3RvciBBbmFseXNpcyAoQ0ZBKS4gVGhlIHN1Z2dlc3RlZCBndWlkZWxpbmVzIGFyZToNCiAgKyBBIGxvYWRpbmcgKiptYWduaXR1ZGUgZ3JlYXRlciB0aGFuIDAuNSoqIGluZGljYXRlcyB0aGF0IHRoZSBpdGVtIHNoYXJlcyBhdCBsZWFzdCAyNSUgb2YgaXRzIHZhcmlhbmNlIHdpdGggdGhlIGxhdGVudCBmYWN0b3IuIEluIHRoZSBmb2xsb3dpbmcgdGFibGUsIHdlIHJlcG9ydCB0aGUgbWluaW11bSBsb2FkaW5nIGZvciBlYWNoIGluc3RydW1lbnQgdW5kZXIgdGhlIGNvbHVtbiBgc3RkLmFsbC5taW5gLg0KICArIEFsbCBsb2FkaW5ncyBtdXN0IGJlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgKHAgPCAwLjA1KS4gV2UgcmVwb3J0IHRoZSBtYXhpbXVtIHAtdmFsdWUgZm9yIGVhY2ggaW5zdHJ1bWVudCB1bmRlciB0aGUgY29sdW1uIGBwdmFsLm1heGAuDQoNCiogKipTdGFuZGFyZGl6ZWQgUm9vdCBNZWFuIFNxdWFyZSBSZXNpZHVhbCAoU1JNUikqKiBtZWFzdXJlcyB0aGUgZ29vZG5lc3Mtb2YtZml0IG9mIHRoZSBDRkEgbW9kZWwuIEl0IHJlcHJlc2VudHMgdGhlIGF2ZXJhZ2Ugc3RhbmRhcmRpemVkIHJlc2lkdWFsIGJldHdlZW4gdGhlIG9ic2VydmVkIGFuZCBwcmVkaWN0ZWQgY29ycmVsYXRpb24gbWF0cmljZXMuIEEgbG93ZXIgdmFsdWUgaW5kaWNhdGVzIGEgYmV0dGVyIGZpdCwgd2l0aCBhIHN1Z2dlc3RlZCBjdXRvZmYgb2YgKipsZXNzIHRoYW4gMC4wOCoqLg0KDQoqICoqQ29tcGFyYXRpdmUgRml0IEluZGV4IChDRkkpKiogaXMgYW5vdGhlciBnb29kbmVzcy1vZi1maXQgbWVhc3VyZSBmb3IgdGhlIENGQS4gSXQgY29tcGFyZXMgdGhlIHNwZWNpZmllZCBtb2RlbCB0byBhIG51bGwgKGluZGVwZW5kZW5jZSkgbW9kZWwuIEEgaGlnaGVyIHZhbHVlIGluZGljYXRlcyBhIGJldHRlciBmaXQsIHdpdGggYSBzdWdnZXN0ZWQgY3V0b2ZmIG9mICoqZ3JlYXRlciB0aGFuIDAuOSoqLg0KDQoqICoqVHVja2VyLUxld2lzIEluZGV4IChUTEkpKiogYWxzbyBtZWFzdXJlcyB0aGUgZ29vZG5lc3Mtb2YtZml0IG9mIHRoZSBDRkEuIEl0cyBpbnRlcnByZXRhdGlvbiBhbmQgdXNhZ2UgYXJlIHNpbWlsYXIgdG8gdGhvc2Ugb2YgdGhlIENGSS4NCg0KQWZ0ZXIgc29tZSBleHBsb3JhdG9yeSBhbmFseXNpcywgd2UgZHJvcHBlZCBhIGZldyBpdGVtcyBmcm9tIHRoZSBUZWNobm9sb2d5IEluc3RydW1lbnQgYW5kIGRlZmluZWQgdHdvIHN1Y3NjYWxlcyBvZiB0aGUgaW5pdGlhbCByZXNvdXJjZSBpbnN0cnVtZW50czogKip1c2Ugb2YgcmVzb3VyY2UqKiBhbmQgKipzdHVkZW50IGVuZ2FnZW1lbnQqKi4NCg0KDQpUaGUgZmluYWwgcmVzdWx0cyBvbiB0aGUgc3RydWN0IHZhbGlkaXR5IG1lYXN1cmVzIGFyZSBzdW1tYXJpemVkIGluIHRoZSBmb2xsb3dpbmcgdGFibGUuDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCBldmFsID0gVFJVRX0NCmNmYS5hbmFseXNpcyA8LSBmdW5jdGlvbihkYXRhc2V0KXsNCiAgI2RhdGFzZXQgPC0gQ29tcC5BbnhpZXR5DQogIHByZWRpY3RvcnMgPC0gbmFtZXMoZGF0YXNldFssIC0xXSkgIA0KICBuMCA8LSBsZW5ndGgocHJlZGljdG9ycykNCiAgY2ZhLm1vZGVsIDwtICBwYXN0ZSgibGF0ZW50ID1+IiwgcGFzdGUocHJlZGljdG9ycywgY29sbGFwc2UgPSAiICsgIikpDQogIGNmYS5maXQgPC0gY2ZhKGNmYS5tb2RlbCwgZGF0YSA9IGRhdGFzZXRbLCAtMV0sIGVzdGltYXRvciA9ICJNTE0iKQ0KICByZXN1bHRzIDwtIHN1bW1hcnkoY2ZhLmZpdCwgc3RhbmRhcmRpemVkID0gVFJVRSwgZml0Lm1lYXN1cmVzID0gVFJVRSwgcnNxdWFyZSA9IFRSVUUpDQogIHN0ZC5hbGwubWluIDwtIG1pbihyZXN1bHRzJHBlJHN0ZC5sdlsxOm4wXSkNCiAgcHZhbC5tYXggPC0gbWF4KHJlc3VsdHMkcGUkcHZhbHVlWzI6bjBdKQ0KICBzcm1yIDwtIHJlc3VsdHMkZml0WyJzcm1yIl0NCiAgY2ZpIDwtIHJlc3VsdHMkZml0WyJjZmkiXQ0KICB0bGkgPC0gcmVzdWx0cyRmaXRbInRsaSJdDQogICNybXNlYSA8LSByZXN1bHRzJGZpdFsicm1zZWEiXQ0KICBjYmluZChzdGQuYWxsLm1pbiA9IHN0ZC5hbGwubWluLCBwdmFsLm1heCA9IHB2YWwubWF4LCBzcm1yID0gc3JtciwgY2ZpID0gY2ZpLCAgdGxpID0gdGxpKQ0KfQ0KYGBgDQoNCg0KYGBge3IgZWNobyA9IFRSVUUsIGV2YWwgPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmc9RkFMU0V9DQphbnhpZXR5Lm1lYS52bGlkIDwtY2ZhLmFuYWx5c2lzKEFueGlldHkubWVhKQ0KYW54aWV0eS5tbGEudmxpZCA8LWNmYS5hbmFseXNpcyhBbnhpZXR5Lm1sYSkNCmFueGlldHkudmxpZCA8LWNmYS5hbmFseXNpcyhDb21wLkFueGlldHkpDQplZmZpY2FjeS52bGlkIDwtY2ZhLmFuYWx5c2lzKENvbXAuU2VsZkVmZmljYWN5KQ0KdGVjaC52bGlkIDwtY2ZhLmFuYWx5c2lzKENvbXAuVGVjaG5vbG9neSkNCmNvb3BlcmF0aXZlLnZsaWQgPC1jZmEuYW5hbHlzaXMoQ29tcC5Db29wb3JhdGl2ZSkNCmRlZHVjdGl2ZS52bGlkIDwtY2ZhLmFuYWx5c2lzKENvbXAuRGVkdWN0aXZlKQ0KZGVtby52bGlkIDwtY2ZhLmFuYWx5c2lzKENvbXAuRGVtb25zdHJhdGlvbikNCmluZHVjdGl2ZS52bGlkIDwtY2ZhLmFuYWx5c2lzKENvbXAuSW5kdWN0aXZlKQ0KaW50ZWdyYXRlLnZsaWQgPC1jZmEuYW5hbHlzaXMoQ29tcC5JbnRlZ3JhdGl2ZSkNCmxlY3R1cmUudmxpZCA8LWNmYS5hbmFseXNpcyhDb21wLkxlY3R1cmVUeXBlKQ0KcmVwZXRpdmUudmxpZCA8LWNmYS5hbmFseXNpcyhDb21wLlJlcGV0aXRpdmUpDQplbmdhZ2UudmxpZCA8LWNmYS5hbmFseXNpcyhDb21wLkVuZ2FnZSkNCnJlc291cmNlLnZsaWQgPC1jZmEuYW5hbHlzaXMoQ29tcC5SZXNvdXJjZSkNCiMjDQp2bGlkLnRhYmxlIDwtcmJpbmQoYW54aWV0eS5tZWEgPSBhbnhpZXR5Lm1lYS52bGlkLCBhbnhpZXR5Lm1sYSA9IGFueGlldHkubWxhLnZsaWQsIA0KICAgICAgICAgICAgICAgICAgYW54aWV0eSA9IGFueGlldHkudmxpZCwgc2VsZi5lZmZpY2FjeSA9IGVmZmljYWN5LnZsaWQsDQogICAgICAgICAgICAgICAgICB0ZWNobm9sb2d5ID0gdGVjaC52bGlkLCBjb29wZXJhdGl2ZSA9IGNvb3BlcmF0aXZlLnZsaWQsDQogICAgICAgICAgICAgICAgICBkZWR1Y3RpdmUgPSBkZWR1Y3RpdmUudmxpZCwgZGVtb25zdHJhdGlvbiA9IGRlbW8udmxpZCwNCiAgICAgICAgICAgICAgICAgIGluZHVjdGl2ZSA9IGluZHVjdGl2ZS52bGlkLCBpbnRlZ3JhdGUgPSBpbnRlZ3JhdGUudmxpZCwNCiAgICAgICAgICAgICAgICAgIGxlY3R1cmUgPSBsZWN0dXJlLnZsaWQsIHJlcGV0aXRpdmUgPSByZXBldGl2ZS52bGlkLCANCiAgICAgICAgICAgICAgICAgIGVuZ2FnZSA9IGVuZ2FnZS52bGlkLCByZXNvdXJjZSA9IHJlc291cmNlLnZsaWQpDQpyb3cubmFtZSA8LSBjKCJhbnhpZXR5Lm1lYSIsICJhbnhpZXR5Lm1sYSIsICJhbnhpZXR5IiwgInNlbGYuZWZmaWNhY3kiLCANCiAgICAgICAgICAgICAgInRlY2hub2xvZ3kiLCAiY29vcGVyYXRpdmUiLA0KICAgICAgICAgICAgICAiZGVkdWN0aXZlIiwgImRlbW9uc3RyYXRpb24iLCAiaW5kdWN0aXZlIiwgImludGVncmF0ZSIsDQogICAgICAgICAgICAgICJsZWN0dXJlIiwgInJlcGV0aXRpdmUiLCAiZW5nYWdlIiwgInJlc291cmNlIikNCmNvbC5uYW1lIDwtIGMoInN0ZC5hbGwubWluIiwgInB2YWwubWF4IiwgInNybXIiLCAiY2ZpIiwgICJ0bGkiKQ0Kcm93bmFtZXModmxpZC50YWJsZSkgPC0gcm93Lm5hbWUNCmNvbG5hbWVzKHZsaWQudGFibGUpIDwtIGNvbC5uYW1lDQpwYW5kZXIodmxpZC50YWJsZSkNCmBgYA0KDQpUaGUgY29uc3RydWN0IHZhbGlkaXR5IG9mIGFsbCBtdWx0aS1pdGVtIGluc3RydW1lbnRzIHdhcyBhc3Nlc3NlZCB1c2luZyBDb25maXJtYXRvcnkgRmFjdG9yIEFuYWx5c2lzIChDRkkpLiBUaGUgcmVzdWx0cyBjb25maXJtZWQgdGhhdCBtb3N0IHNjYWxlcyBtZWV0IGVzdGFibGlzaGVkIHBzeWNob21ldHJpYyBzdGFuZGFyZHMuIFRoZSBtb2pwcml0eSBvZiB0aGUga2V5IGZpdCBpbmRpY2VzLCBpbmNsdWRpbmcgQ0ZJIGFuZCBUTEksIGV4Y2VlZGVkIHRoZSByZWNvbW1lbmRlZCB0aHJlc2hvbGQgb2YgMC45MCwgd2hpbGUgdGhlIFNSTVIgZmVsbCBiZWxvdyB0aGUgMC4wOCBjdXRvZmYsIGluZGljYXRpbmcgYSBnb29kIG1vZGVsIGZpdC4gRnVydGhlcm1vcmUsIGFsbCBmYWN0b3IgbG9hZGluZ3Mgd2VyZSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IChwIDwgLjA1KSBhbmQgc3Vic3RhbnRpYWwgaW4gbWFnbml0dWRlIChleGNlZWRpbmcgMC40KSwgZGVtb25zdHJhdGluZyBzdHJvbmcgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIHRoZSBpdGVtcyBhbmQgdGhlaXIgaW50ZW5kZWQgbGF0ZW50IGNvbnN0cnVjdHMuIEluIHN1bW1hcnksIHRoZSB2YWxpZGl0eSBhbmFseXNpcyBjb25maXJtcyB0aGF0IHRoZSBpbnN0cnVtZW50cyB1c2VkIGluIHRoaXMgc3R1ZHkgYXJlIHJvYnVzdCBhbmQgYXBwcm9wcmlhdGUgZm9yIG1lYXN1cmluZyB0aGVpciByZXNwZWN0aXZlIGNvbmNlcHRzLg0KDQoqKlJlbWFya3MqKjogKDEpLiBUaGUgYWJvdmUgdmFsaWRpdHkgbWVhc3VyZXMgYmFzZWQgb24gdGhlIGl0ZW1zIGZvbGxvdyBtdWx0aS12YXJpYXRlIG5vcm1hbCBkaXN0cmlidXRpb24sIFRoaXMgaXMgYSBzdHJvbmcgYXNzdW1wdGlvbi4gVGhlIGl0ZW1zIGluIGVhY2ggaW5zdHJ1bWVudCBhcmUgbm90IGNvbnRpbm91cy4gVGhpcyBpbmZsdWVuY2VzIHNvbWUgb2YgdGhlIHZhbGlkaXR5IG1lYXN1cmUuICgyKS4gSW4gcHJhY3RpY2UsIHdlIGNhbiB1c2Ugc29tZSBkZXNjcmlwdGl2ZSBhcHByb2FjaGVzIHRvIHZpc3VhbCBjaGVjayB3aXRoIGFzc3VtaW5nIG11bHRpLXZhcmlhdGUgbm9ybWFsaXR5LiANCg0KDQojIyBSZWxpYW5iaWxpdHkgQW5hbHlzaXMNCg0KKipSZWxpYWJpbGl0eSoqIG9mIGEgbXVsdGktaXRlbSBzdXJ2ZXkgaW5zdHJ1bWVudCBhbnN3ZXJzIHRoZSBxdWVzdGlvbjogIklmIEkgbWVhc3VyZSB0aGUgc2FtZSB0aGluZyBtdWx0aXBsZSB0aW1lcywgd2lsbCBJIGdldCBhIGNvbnNpc3RlbnQgcmVzdWx0PyIgSXQgbWVhc3VyZXMgaG93IHdlbGwgdGhlIGl0ZW1zIHRoYXQgYXJlIHN1cHBvc2VkIHRvIG1lYXN1cmUgdGhlIHNhbWUgY29uc3RydWN0IGhhbmcgdG9nZXRoZXIuIA0KDQoqKkludGVybmFsIENvbnNpc3RlbmN5KiogaXMgdGhlIG1vc3QgY29tbW9uIGFzc2Vzc21lbnQgZm9yIGEgc3VydmV5IGFkbWluaXN0ZXJlZCBvbmNlLiBJdCBtZWFzdXJlcyB0aGUgZGVncmVlIHRvIHdoaWNoIGl0ZW1zIGluIGEgc2NhbGUgYXJlIGNvcnJlbGF0ZWQgd2l0aCBlYWNoIG90aGVyLiBUd28gd2VsbC1rbm93biBpbnRlcm5hbCBjb25zaXN0ZW5jeSBtZWFzdXJlcyBhcmUgQ3JvbmJhY2gncyBBbHBoYSAoQ3JvbmFiY2ssIDE5NTEpIGFuZCBNY0RvbmFsZCdzIE9tZWdhICgxOTk5KS4gKipNY0RvbmFsZCdzIE9tZWdhKiogaXMgbW9yZSByb2J1c3QgdGhhbiAqKkNyb25iYWNoJ3MgQWxwaGEqKi4gIA0KDQoqKkNyb25iYWNoJ3MgQWxwaGEqKiBhbmQgKipNY0RvbmFsZCdzIE9tZWdhKiogdHlwaWNhbGx5IHJhbmdlIGZyb20gMCB0byAxLiBUaGUgc3VnZ2VzdGVkIGN1dC1vZmZzIGFyZSBnaXZlbiBiZWxvdy4NCg0KKiBgPiAwLjlgOiBFeGNlbGxlbnQNCg0KKiBgMC44IC0gMC45YDogR29vZA0KDQoqIGAwLjcgLSAwLjhgOiBBY2NlcHRhYmxlDQoNCiogYDwgMC43YDogUG9vciAobWF5IGhhdmUgaXRlbXMgdGhhdCBkb24ndCAiYmVsb25nIikNCg0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGV2YWwgPSBUUlVFfQ0KUmVsaWFiaWxpdHkuZnVuID0gZnVuY3Rpb24oZGF0YWZyYW1lKXsNCiAgb21lZ2EgPC0gcHN5Y2g6Om9tZWdhKGRhdGFmcmFtZVssIC0xXSwgbmZhY3RvcnMgPSAxLCBwbG90ID0gRkFMU0UpDQogIHJlbGlhYiA8LWNiaW5kKG9tZWdhJGFscGhhLCBvbWVnYSRvbWVnYS50b3QpDQogIHJlbGlhYg0KICB9DQpgYGANCg0KDQpgYGB7ciBlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZz1GQUxTRX0NCmFueGlldHkubWVhLnJlbCA8LSBSZWxpYWJpbGl0eS5mdW4oQW54aWV0eS5tZWEpDQphbnhpZXR5Lm1sYS5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKEFueGlldHkubWxhKQ0KYW54aWV0eS5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuQW54aWV0eSkNCmVmZmljYWN5LnJlbCA8LSBSZWxpYWJpbGl0eS5mdW4oQ29tcC5TZWxmRWZmaWNhY3kpDQp0ZWNoLnJlbCA8LSBSZWxpYWJpbGl0eS5mdW4oQ29tcC5UZWNobm9sb2d5KQ0KY29vcGVyYXRpdmUucmVsIDwtIFJlbGlhYmlsaXR5LmZ1bihDb21wLkNvb3BvcmF0aXZlKQ0KZGVkdWN0aXZlLnJlbCA8LSBSZWxpYWJpbGl0eS5mdW4oQ29tcC5EZWR1Y3RpdmUpDQpkZW1vLnJlbCA8LSBSZWxpYWJpbGl0eS5mdW4oQ29tcC5EZW1vbnN0cmF0aW9uKQ0KaW5kdWN0aXZlLnJlbCA8LSBSZWxpYWJpbGl0eS5mdW4oQ29tcC5JbmR1Y3RpdmUpDQppbnRlZ3JhdGUucmVsIDwtIFJlbGlhYmlsaXR5LmZ1bihDb21wLkludGVncmF0aXZlKQ0KbGVjdHVyZS5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuTGVjdHVyZVR5cGUpDQpyZXBldGl2ZS5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuUmVwZXRpdGl2ZSkNCiNhZnRlci5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuQWZ0ZXJDbGFzcykNCiNpbi5jbGFzcy5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuSW5DbGFzcykNCmVuZ2FnZS5yZWwgPC0gUmVsaWFiaWxpdHkuZnVuKENvbXAuRW5nYWdlKQ0KcmVzb3VyY2UucmVsIDwtIFJlbGlhYmlsaXR5LmZ1bihDb21wLlJlc291cmNlKQ0KIyMNClJlbC50YWJsZSA8LXJiaW5kKGFueGlldHkubWVhID0gYW54aWV0eS5tZWEucmVsLCBhbnhpZXR5Lm1sYSA9IGFueGlldHkubWxhLnJlbCwNCiAgICAgICAgICAgICAgICAgIGFueGlldHkgPSBhbnhpZXR5LnJlbCwgc2VsZi5lZmZpY2FjeSA9IGVmZmljYWN5LnJlbCwNCiAgICAgICAgICAgICAgICAgIHRlY2hub2xvZ3kgPSB0ZWNoLnJlbCwgY29vcGVyYXRpdmUgPSBjb29wZXJhdGl2ZS5yZWwsDQogICAgICAgICAgICAgICAgICBkZWR1Y3RpdmUgPSBkZWR1Y3RpdmUucmVsLCBkZW1vbnN0cmF0aW9uID0gZGVtby5yZWwsDQogICAgICAgICAgICAgICAgICBpbmR1Y3RpdmUgPSBpbmR1Y3RpdmUucmVsLCBpbnRlZ3JhdGUgPSBpbnRlZ3JhdGUucmVsLA0KICAgICAgICAgICAgICAgICAgbGVjdHVyZSA9IGxlY3R1cmUucmVsLCByZXBldGl0aXZlID0gcmVwZXRpdmUucmVsLCANCiAgICAgICAgICAgICAgICAgIGVuZ2FnZSA9IGVuZ2FnZS5yZWwsIHJlc291cmNlID0gcmVzb3VyY2UucmVsKQ0Kcm93Lm5hbWUgPC0gYygiYW54aWV0eS5tZWEiLCAiYW54aWV0eS5tbGEiLA0KICAgICAgICAgICAgICAiYW54aWV0eSIsICJzZWxmLmVmZmljYWN5IiwgInRlY2hub2xvZ3kiLCAiY29vcGVyYXRpdmUiLA0KICAgICAgICAgICAgICAiZGVkdWN0aXZlIiwgImRlbW9uc3RyYXRpb24iLCAiaW5kdWN0aXZlIiwgImludGVncmF0ZSIsDQogICAgICAgICAgICAgICJsZWN0dXJlIiwgInJlcGV0aXRpdmUiLCAiZW5nYWdlIiwgInJlc291cmNlIikNCmNvbC5uYW1lIDwtIGMoIkNyb25iYWNoIGFscGhhIiwgIk1jRG9uYWxkJ3MgT21lZ2EiKQ0Kcm93bmFtZXMoUmVsLnRhYmxlKSA8LSByb3cubmFtZQ0KY29sbmFtZXMoUmVsLnRhYmxlKSA8LSBjb2wubmFtZQ0KcGFuZGVyKFJlbC50YWJsZSkNCmBgYA0KDQpXZSBjYW4gc2VlIGZyb20gdGhlIGFib3ZlIHRhYmxlIHRoYXQgYWxsIGNhbGN1bGF0ZWQgY29lZmZpY2llbnRzIGV4Y2VlZGVkIHRoZSByZWNvbW1lbmRlZCB0aHJlc2hvbGQgb2YgMC43LCBpbmRpY2F0aW5nIGdvb2QgcmVsaWFiaWxpdHkuIFRoZSByZXN1bHRzIGNvbmZpcm0gdGhhdCB0aGUgaW5zdHJ1bWVudHMgdXNlZCBpbiB0aGlzIHN0dWR5IGRlbW9uc3RyYXRlIHN0cm9uZyBpbnRlcm5hbCBjb25zaXN0ZW5jeSwgbWVhbmluZyB0aGUgaXRlbXMgd2l0aGluIGVhY2ggc2NhbGUgcmVsaWFibHkgbWVhc3VyZSB0aGUgc2FtZSB1bmRlcmx5aW5nIGNvbnN0cnVjdC4NCg0KDQoNCiMgQ29tcG9zaXRlIFNjb3JpbmcNCg0KVGhlIGNvcmUgcHVycG9zZSBvZiBjb25zdHJ1Y3RpbmcgbXVsdGktaXRlbSBzdXJ2ZXlzIGlzIHRvIG1lYXN1cmUgY29tcGxleCBjb25jZXB0cyB3aXRoIGdyZWF0ZXIgYWNjdXJhY3ksIHJlbGlhYmlsaXR5LCBhbmQgZGVwdGggdGhhbiBhIHNpbmdsZSBxdWVzdGlvbiBldmVyIGNvdWxkLiBBbGwgaW5zdHJ1bWVudHMgdXNlZCBpbiB0aGlzIHN0dWR5IGFyZSBiYXNlZCBvbiBhIHNpbmdsZS1mYWN0b3IgY29uc3RydWN0IHVzaW5nIHRoZSBMaWtlcnQgc2NhbGVzLiBUaGUgY29tbW9ubHkgdXNlZCBtZXRob2RzIGZvciBkZWZpbmluZyBzaW5nbGUgaW5kZXggdG8gY2FwdHVyZSB0aGUgaW5mb3JtYXRpb24gb2YgdGhlIHNpbmdsZS1mYWN0b3IgY29uc3RydWN0IGFyZSBjbGFzc2lmaWVkIGluIHRocmVlIGNhdGVnb3JpZXMNCg0KIyMgU3VtbWluZyB0aGUgUmF3IExpa2VydCBTY29yZXMNCg0KVGhlIHNpbXBsZXN0IGFwcHJvYWNoIGlzIHRvIHN1bSB0aGUgcmF3IExpa2VydCBzY29yZXMgaW50byBhIGNvbXBvc2l0ZSBzY29yZSB0aGF0IHJlcHJlc2VudHMgYSBzaW5nbGUgZmFjdG9yIHdpdGhpbiB0aGUgc3VydmV5IGNvbnN0cnVjdC4gVGhpcyBtZXRob2QgaXMgdmFsaWQgcHJvdmlkZWQgdGhhdCBhbGwgcXVlc3Rpb25uYWlyZSBpdGVtcyBhcmUgZXF1YWxseSBpbXBvcnRhbnQsIGFzIGVhY2ggY2FwdHVyZXMgYSBzaW1pbGFyIGFtb3VudCBvZiBpbmZvcm1hdGlvbiBhYm91dCB0aGUgdW5kZXJseWluZyBmYWN0b3IuDQoNCkhvd2V2ZXIsIHRoaXMgYXBwcm9hY2ggaXMgdmlvbGF0ZWQgaW4gc2V2ZXJhbCBjcml0aWNhbCBzY2VuYXJpb3MsIGxlYWRpbmcgdG8gYSBiaWFzZWQgYW5kIHVucmVsaWFibGUgY29tcG9zaXRlIHNjb3JlLiBGb3IgZXhhbXBsZSwgICoqVmlvbGF0aW9uIG9mIEVxdWFsIEltcG9ydGFuY2UqKjogVGhlIGNvcmUgYXNzdW1wdGlvbiBpcyB0aGF0IGVhY2ggaXRlbSBpcyBhIGVxdWFsbHkgc3Ryb25nIGluZGljYXRvciBvZiB0aGUgY29uc3RydWN0LiBJbiByZWFsaXR5LCBpdGVtcyBvZnRlbiBoYXZlIGRpZmZlcmVudCBsZXZlbHMgb2YgaW1wb3J0YW5jZS4gU3VtbWluZyBpdGVtcyB3aXRoIGhpZ2ggYW5kIGxvdyBsZXZlbHMgb2YgaW1wb3J0YW5jZSBlcXVhbGx5IGdpdmVzIHVuZHVlIHdlaWdodCB0byB3ZWFrZXIgaW5kaWNhdG9ycywgZWZmZWN0aXZlbHkgZGlsdXRpbmcgdGhlIGNvbXBvc2l0ZSBzY29yZSB3aXRoIG5vaXNlIGFuZCByZWR1Y2luZyBpdHMgdmFsaWRpdHkuIA0KDQoNCiMjIEZBIEFwcHJvYWNoDQoNCkNvbmZpcm1hdG9yeSBGYWN0b3IgQW5hbHlzaXMgKENGQSkgaXMgYSB2ZXJ5IGNvbW1vbiBhbmQgb2Z0ZW4gcHJhY3RpY2FsIGFwcHJvYWNoIHRvIHZhbGlkYXRpbmcgc3VydmV5IGluc3RydW1lbnRzIGFuZCBjcmVhdGUgKHdlaWdodGVkKSBjb21wb3NpdGUgc2NvcmUuIEl0IGlzIGEgZGlzdHJpYnV0aW9uIGRlcGVuZGVudCBzdGF0aXN0aWNhbCBtZXRob2QuIEhvd2V2ZXIsIGl0IGNvbWVzIHdpdGggYSBzZXQgb2YgZGlzdGluY3Qgc29tZSBkaXNhZHZhbnRhZ2VzIHBhcnRpY3VsYXJseSB0aGUgYXNzdW1wdGlvbiBvZiBtdWx0aS12YXJpYXRlIG5vcm1hbCBkaXN0cmlidXRpb24uIEZhY3RvciBsb2FkaW5ncyBpbiBDRkEgYXJlIGVzdGltYXRlZCBiYXNlZCBvbiB0aGUgbWF4aW11bSBsaWtlbGlob29kIHdoaWNoIGlzIGRlZmluZWQgYmFzZWQgb24gbXVsdGl2YXJpYXRlIG5vcm1hbCBkaXN0cmlidXRpb24uDQoNCldlIGhhdmUgdXNlZCBDRkEgdG8gdmFsaWRhdGUgdGhlIGluc3RydW1lbnQuIFNpbmNlIGFsbCBpbnN0cnVtZW50cyBpbiB0aGlzIHN0dWR5IGFyZSBzaW5nbGUtZmFjdG9yIGNvbnN0cnVjdHMsIHdlIHdpbGwgY2FsY3VsYXRlIHRoZSBzaW5nbGUgY29tcG9zaXRlIHNjb3JlIGZvciBlYWNoIGluc3RydW1lbnQgdXNpbmcgQ0ZBLg0KDQoNCiMjIFBDQSBBcHByb2FjaCANCg0KUENBIGlzIGEgZGlzdHJpYnV0aW9uLWZyZWUgbWV0aG9kIHdoaWNoIHVzZXMgYSBtYXRoZW1hdGljYWwgdHJhbnNmb3JtYXRpb24gKG9ydGhvZ29uYWwgcm90YXRpb24pIHRvIG9idGFpbiBhIG5ldyBjb29yZGluYXRlIHN5c3RlbSBzdWNoIHRoYXQgdGhlIGZpcnN0IG5ldyBheGlzIChQcmluY2lwYWwgQ29tcG9uZW50IDEpIHBvaW50cyBpbiB0aGUgZGlyZWN0aW9uIG9mIHRoZSBtYXhpbXVtIHZhcmlhbmNlIGluIHRoZSBkYXRhLiBUaGUgc2Vjb25kIGF4aXMgaXMgb3J0aG9nb25hbCB0byB0aGUgZmlyc3QgYW5kIHBvaW50cyBpbiB0aGUgZGlyZWN0aW9uIG9mIHRoZSBuZXh0IGdyZWF0ZXN0IHZhcmlhbmNlLCBhbmQgc28gb24uIFRoZSBuZXcgYXhlcyAoY29tcG9uZW50cykgYXJlIGxpbmVhciBjb21iaW5hdGlvbnMgb2YgdGhlIG9yaWdpbmFsIHZhcmlhYmxlcy4gQ29uc2VxdWVudGx5LCBhIGstaXRlbSBpbnN0cnVtZW50IHdpbGwgZ2VuZXJhdGUgayBwcmluY2lwYWwgY29tcG9uZW50cy4NCg0KQWx0aG91Z2ggdGhlcmUgZGViYXRlcyBvbiB1c2luZyBQQ0EgaW4gcHN5Y2hvbWV0cmljcywgdGhlIGVhcmxpZXN0IGFwcGxpY2F0aW9ucyBvZiBQQ0EgaW4gc3VydmV5IHJlc2VhcmNoIGNhbiBiZSB0cmFjZWQgYmFjayB0byAxOTUwcyAoU3RvdWZmZXIgZXQgYWwuLCAxOTUwOyBDYXR0ZWxsLCAxOTUyOyBEdW5jYW4sIDE5ICkuIFRoZSBnb2FsIHdhcyBjb25zaXN0ZW50bHkgdGhlIHNhbWUgYXMgaXQgaXMgdG9kYXk6IHRvIHVuY292ZXIgdGhlIHNpbXBsZSwgbGF0ZW50IHN0cnVjdHVyZXMgdGhhdCB1bmRlcmxpZSB0aGUgY29tcGxleCBjb3JyZWxhdGlvbnMgYW1vbmcgbWFueSBvYnNlcnZlZCBzdXJ2ZXkgcXVlc3Rpb25zLg0KDQo8Zm9udCBjb2xvciA9ICJyZWQiPioqQWRqdXN0aW5nIERpcmVjdGlvbiBvZiBQQ3MqKjwvZm9udD4NCg0KUHJpbmNpcGFsIENvbXBvbmVudHMgKFBDcykgYXJlIG5ldywgdW5jb3JyZWxhdGVkIGF4ZXMsIHdoZXJlYXMgTGlrZXJ0IHNjb3JlcyBhcmUgb3JkaW5hbCByYXRpbmcgc2NhbGVzLiBXaGVuIHVzaW5nIFBDcyB0byByZXByZXNlbnQgdGhlc2UgcmF0aW5nIHNjYWxlcywgdGhlaXIgZGlyZWN0aW9uIG11c3QgYmUgYWxpZ25lZC4gQSBzaW1wbGUgbWV0aG9kIHRvIGRldGVybWluZSBpZiBhIFBDJ3MgZGlyZWN0aW9uIG5lZWRzIHRvIGJlIHJldmVyc2VkIGlzIHRvIGV4YW1pbmUgdGhlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50cyBiZXR3ZWVuIHRoZSBuYWl2ZSBjb21wb3NpdGUgYXZlcmFnZSBzY29yZXMgYW5kIHRoZSBQQyBzY29yZXMuIElmIHRoZSBjb3JyZWxhdGlvbiBpcyBuZWdhdGl2ZSwgdGhlIGNvcnJlc3BvbmRpbmcgUEMgc2hvdWxkIGJlIHJldmVyc2VkOyBvdGhlcndpc2UsIHRoZSBkZWZhdWx0IGF4aXMgc2hvdWxkIGJlIHJldGFpbmVkLg0KDQoqKkNvbXBvc2l0ZSBTY29yaW5nIFVzaW5nIFRoZSBmaXJzdCBQcmluY2lwYWwgQ29tcG9uZW50IChQQzEpKioNCg0KVGhpcyBhcHByb2FjaCBoYXMgYmVlbiBlbXBsb3llZCBzaW5jZSB0aGUgMTk1MHMgKGUuZy4sIEd1dHRtYW4sIDE5NTQ7IEhpcnNjaGJlcmcgJiBTdGFuZGlzaCwgMTk1OTsgRHVuY2FuLCAxOTYxKS4gVGhlIHJhdGlvbmFsZSBmb3IgdXNpbmcgdGhlIGZpcnN0IHByaW5jaXBhbCBjb21wb25lbnQgaXMgdGhhdCBpdCBhY2NvdW50cyBmb3IgdGhlIG1heGltdW0gdmFyaWFuY2UgaW4gdGhlIGRhdGEgYW5kIGNvbnN0aXR1dGVzIGEgbGluZWFyIGNvbWJpbmF0aW9uIG9mIGFsbCBpdGVtcy4gTXVjaCBsaWtlIGluIGNvbmZpcm1hdG9yeSBmYWN0b3IgYW5hbHlzaXMgKENGQSksIHRoZSBmaXJzdCBwcmluY2lwYWwgY29tcG9uZW50IGNhbiBiZSBpbnRlcnByZXRlZCBhcyBhIHdlaWdodGVkIGF2ZXJhZ2Ugb2YgaW5kaXZpZHVhbCBpdGVtIHNjb3Jlcy4NCg0KDQoqKkNvbXBvc2l0ZSBTY29yaW5nIFVzaW5nIFdlaWdodGVkIEF2ZXJhZ2Ugb2YgSXRlbSBTY29yZXMgQWNyb3NzIEFsbCBQQ3M6IDxmb250IGNvbG9yID0gInJlZCI+RG91Ymx5IFdlaWdodGVkIEF2ZXJhZ2U8L2ZvbnQ+KioNCg0KSW4gbWFueSByZWFsLXdvcmxkIGRhdGFzZXRzLCB0aGUgdW5kZXJseWluZyBjb25zdHJ1Y3RzIGFyZSBpbmhlcmVudGx5IG11bHRpZGltZW5zaW9uYWwuIENvbnNlcXVlbnRseSwgbGltaXRpbmcgdGhlIGFuYWx5c2lzIHRvIHRoZSBmaXJzdCBwcmluY2lwYWwgY29tcG9uZW50IG1lYW5zIGRpc2NhcmRpbmcgc3RydWN0dXJlZCBpbmZvcm1hdGlvbiBjYXB0dXJlZCBieSBzdWJzZXF1ZW50IGNvbXBvbmVudHMgKFBDMiwgUEMzLCBldGMuKS4gQSBjb21wb3NpdGUgc2NvcmUgdGhhdCBpbnRlZ3JhdGVzIGFsbCBzaWduaWZpY2FudCBjb21wb25lbnRzIG9mZmVycyBhIG1vcmUgaG9saXN0aWMgYW5kIGFjY3VyYXRlIHN1bW1hcnkgbWVhc3VyZS4gVGhlIHByaW1hcnkgYmFycmllciB0byB0aGUgd2lkZXNwcmVhZCBhZG9wdGlvbiBvZiB0aGlzIG1ldGhvZCBpcyB0aGUgY2hhbGxlbmdlIGFzc29jaWF0ZWQgd2l0aCBpbnRlcnByZXRpbmcgdGhlIGNvbXBvc2l0ZSBpbmRleCdzIHN0cnVjdHVyZS4NCg0KDQoNCiMjIENvbXBvc2l0ZSBTY29yZXMgVG8gQmUgQ3JlYXRlZA0KDQpXZSB3aWxsIGdlbmVyYXRlIGZvdXIgdHlwZXMgb2YgY29tcG9zaXRlIHNjb3JlcyBmb3IgZWFjaCBvZiB0aGUgMTEgaW5zdHJ1bWVudHMgZm9yIHRoZSBwdXJwb3NlIG9mIGVtcGlyaWNhbCBjb21wYXJpc29uLg0KDQoqICoqYXZnKio6IFRoZSBhdmVyYWdlIG9mIHRoZSByYXcgaXRlbSBzY29yZXMuDQoqICoqY2ZhKio6IFRoZSBleHRyYWN0IGNvbmZpcm1hdG9yeSBmYWN0b3IgYW5hbHlzaXMgKGNmYSkgc2NvcmUgKGFsbCBpbnN0cnVtZW50cyBhcmUgYmFzZWQgb24gdGhlIHNpbmdsZS1mYWN0b3IgY29uc3RydWN0KS4NCiogKipwY2ExKio6IFRoZSBmaXJzdCBwcmluY2lwYWwgY29tcG9uZW50IHNjb3Jlcy4NCiogKipwY2Eud3QqKjogVGhlIHdlaWdodGVkIGF2ZXJhZ2Ugb2YgcGNhIHNjb3JlcyBhY3Jvc3MgYWxsIHByaW5jaXBhbCBjb21wb25lbnRzLg0KDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCBldmFsID0gVFJVRX0NCiMjIyMjDQogc2NvcmVzID0gZnVuY3Rpb24oZGYsIGRuKXsNCiAgIyMjIyMjIyMjIyMjIyMjDQogICMgbWVhbiBzY29yZQ0KICAjIyMjIyMjIyMjIyMjIw0KICBkZi5tZWFuIDwtIHJvd01lYW5zKGRmWywgLTFdKQ0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiAgIyMgc2luZ2xlIGZhY3RvciBzY29yZQ0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KICB4LnZhciA8LSBuYW1lcyhkZlssIC0xXSkNCiAgbjAgPC0gbGVuZ3RoKHgudmFyKQ0KICBjZmEubW9kZWwgPC0gIHBhc3RlKCJsYXRlbnQgPX4iLCBwYXN0ZSh4LnZhciwgY29sbGFwc2UgPSAiICsgIikpDQogIGNmYS5maXQgPC0gY2ZhKGNmYS5tb2RlbCwgZGF0YSA9IGRmWywgLTFdLCBlc3RpbWF0b3IgPSAiTUxNIikNCiAgY29tcG9zaXRlLmNmYSA8LSBsYXZQcmVkaWN0KGNmYS5maXQpDQogICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQogICMgcGNhIGFuYWx5c2lzDQogICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQogIHBjYS5tZGwgPC0gcHJjb21wKGRmWywtMV0sIHNjYWxlID0gVFJVRSkNCiAgcGNhMCA8LSBwY2EubWRsJHhbLCAxXQ0KICByMCA9IGNvcihwY2EwLCBkZi5tZWFuKQ0KICBpZihyMCA8IDApIHsNCiAgICAgcGNhLmFsbCA8LSAtcGNhLm1kbCR4DQogIH1lbHNlew0KICAgIHBjYS5hbGwgPC0gcGNhLm1kbCR4DQogIH0NCiAgZmlyc3QucGNhID0gcGNhLmFsbFssMV0NCiAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiAgIyB3ZWlnaHRlZCBwY2Egc2NvcmUNCiAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiAgdmFyLmV4cGxhaW5lZCA8LSgocGNhLm1kbCRzZGV2KV4yKSAvIHN1bSgocGNhLm1kbCRzZGV2KV4yKSAjDQogIGNvbXBvc2l0ZV93ZWlnaHRlZF9wY2EgPC0gYXMubWF0cml4KHBjYS5hbGwpICUqJSAodmFyLmV4cGxhaW5lZCkNCg0KICBvdXRkYXRhIDwtIGFzLmRhdGEuZnJhbWUoY2JpbmQoYXZnID0gZGYubWVhbiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICBwY2ExID0gZmlyc3QucGNhLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHd0LnBjYSA9IGFzLnZlY3Rvcihjb21wb3NpdGVfd2VpZ2h0ZWRfcGNhKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICBjZmEgPSBhcy52ZWN0b3IoY29tcG9zaXRlLmNmYSkpKQ0KICBuYW1lcyhvdXRkYXRhKSA8LSBwYXN0ZTAoZG4sIi4iLCBuYW1lcyhvdXRkYXRhKSwgc2VwID0gIiIpDQogIG91dGRhdGENCiAgfQ0KIyMjDQpBbnhpZXR5Lm1lYS5zY29yZSA9IHNjb3JlcyhBbnhpZXR5Lm1lYSwgIkFueGlldHkubWVhIikNCkFueGlldHkubWxhLnNjb3JlID0gc2NvcmVzKEFueGlldHkubWxhLCAiQW54aWV0eS5tbGEiKQ0KQW54aWV0eS5zY29yZSA9IHNjb3JlcyhDb21wLkFueGlldHksICJBbnhpZXR5IikNClNlbGZFZmZpY2FjeS5zY29yZSA9IHNjb3JlcyhDb21wLlNlbGZFZmZpY2FjeTAsICJTZWxmRWZmaWNhY3kiKQ0KVGVjaG5vbG9neS5zY29yZSA9IHNjb3JlcyhDb21wLlRlY2hub2xvZ3ksICJUZWNobm9sb2d5IikNCkNvb3BvcmF0aXZlLnNjb3JlID0gc2NvcmVzKENvbXAuQ29vcG9yYXRpdmUsICJDb29wb3JhdGl2ZSIpDQpEZWR1Y3RpdmUuc2NvcmUgPSBzY29yZXMoQ29tcC5EZWR1Y3RpdmUsICJEZWR1Y3RpdmUiKQ0KRGVtb25zdHJhdGlvbi5zY29yZSA9IHNjb3JlcyhDb21wLkRlbW9uc3RyYXRpb24sICJEZW1vbnN0cmF0aW9uIikNCkluZHVjdGl2ZS5zY29yZSA9IHNjb3JlcyhDb21wLkluZHVjdGl2ZSwgIkluZHVjdGl2ZSIpDQpJbnRlZ3JhdGl2ZS5zY29yZSA9IHNjb3JlcyhDb21wLkludGVncmF0aXZlLCAiSW50ZWdyYXRpdmUiKQ0KTGVjdHVyZVR5cGUuc2NvcmUgPSBzY29yZXMoQ29tcC5MZWN0dXJlVHlwZSwgIkxlY3R1cmVUeXBlIikNClJlcGV0aXRpdmUuc2NvcmUgPSBzY29yZXMoQ29tcC5SZXBldGl0aXZlLCAiUmVwZXRpdGl2ZSIpDQpFbmdhZ2Uuc2NvcmUgPSBzY29yZXMoQ29tcC5FbmdhZ2UsICJFbmdhZ2UiKQ0KUmVzb3VyY2Uuc2NvcmUgPSBzY29yZXMoQ29tcC5SZXNvdXJjZSwgIlJlc291cmNlIikNCiMjDQpmaW5hbERhdCA8LSBjYmluZChkZW1vZ3JhcGhpY3MsIEFueGlldHkuc2NvcmUsIEFueGlldHkubWVhLnNjb3JlLA0KICAgICAgICAgICAgICAgICAgQW54aWV0eS5tbGEuc2NvcmUsIFNlbGZFZmZpY2FjeS5zY29yZSwgVGVjaG5vbG9neS5zY29yZSwNCiAgICAgICAgICAgICAgICAgIENvb3BvcmF0aXZlLnNjb3JlLCBEZWR1Y3RpdmUuc2NvcmUsIERlbW9uc3RyYXRpb24uc2NvcmUsSW5kdWN0aXZlLnNjb3JlLA0KICAgICAgICAgICAgICAgICAgSW50ZWdyYXRpdmUuc2NvcmUsIExlY3R1cmVUeXBlLnNjb3JlLCBSZXBldGl0aXZlLnNjb3JlLA0KICAgICAgICAgICAgICAgICAgRW5nYWdlLnNjb3JlLCBSZXNvdXJjZS5zY29yZSkNCmBgYA0KDQoNCg0KYGBge3IgZWNobyA9IEZBTFNFLCBldmFsID0gRkFMU0V9DQp3cml0ZS5jc3YoZmluYWxEYXQsICJDOlxcVXNlcnNcXDc1Q1BFTkdcXE9uZURyaXZlIC0gV2VzdCBDaGVzdGVyIFVuaXZlcnNpdHkgb2YgUEFcXERlc2t0b3BcXGNwZW5nXFxXQ1UtVGVhY2hpbmdcXDIwMjVGYWxsXFxNYXRoQXhpZXR5XFxjb21wbGV0ZUFueGlldHlEYXRhLmNzdiIpDQpgYGANCg0KDQoNCiMgU29tZSBHcmFwaGljYWwgRXhwbG9yYXRpb24NCg0KV2UgbmV4dCBleHBsb3JlIHRoZSBkaXN0cmlidXRpb25zIG9mIHRoZSBjcmVhdGVkIGNvbXBvc2l0ZSBzY29yZXMgYW5kIHBlcmZvcm0gc29tZSBlbXBpcmljYWwgY29tcGFyaXNvbnMuIFRoZSBwcmltYXJ5IGdvYWwgb2YgdGhpcyBzdXJ2ZXkgc3R1ZHkgaXMgdG8gaW52ZXN0aWdhdGUgZmFjdG9ycyB0aGF0IGFyZSBhc3NvY2lhdGVkIHdpdGggbWF0aGVtYXRpY3MgYW54aWV0eSAoTUEpIGxldmVscy4gVG8gdGhpcyBlbmQsIHdlIGFsc28gbG9vayB0aGUgZGlzdHJpYnV0aW9ucyBlYWNoIGluZGl2aWR1YWwgaXRlbXMgaW4gdGhlIE1BIGluc3RydW1lbnQuDQoNCg0KIyMgRGlzdHJpYnV0aW9ucyBvZiBDb21wb3NpdGUgU2NvcmVzDQoNClRoZSBmb2xsb3dpbmcgYXJlIGRpc3RyaWJ1dGlvbnMgb2YgZm91ciBnZW5lcmF0ZWQgY29tcG9zaXRlIHNjb3JlcyBhY3Jvc3MgYWxsIGluc3RydW1lbnRzLiBUaGUgcHVycG9zZSBpcyB0byBleGFtaW5lIHRoZSBiZWhhdmlvcnMgb2YgdGhlc2UgY29tcG9zaXRlIHNjb3JlcywgZXNwZWNpYWxseSB0aGUgZG91Ymx5IHdlaWdodGVkIGNvbXBvc2l0ZSBzY29yZSBiYXNlZCBvbiB0aGUgcHJpbmNpcGFsIGNvbXBvbmVudCBhbmFseXNpcy4NCg0KDQpgYGB7ciBlY2hvID0gRkFMU0V9DQojZmluYWwuYW54aWV0eS5kYXQgPC0gcmVhZC5jc3YoImh0dHBzOi8vcGVuZ2RzY2kuZ2l0aHViLmlvL01hdGhBbnhpZXR5L2NvbXBsZXRlQW54aWV0eURhdGEuY3N2IikNCmZpbmFsLmFueGlldHkuZGF0IDwtIGZpbmFsRGF0DQpgYGANCg0KDQpgYGB7cn0NCnBsb3RseS5mdW4gPC0gZnVuY3Rpb24oaW4uZGF0YSl7DQogICBpbi5hdmcgPC0gZGVuc2l0eShpbi5kYXRhWywxXSkNCiAgIGluLnBjMSA8LSBkZW5zaXR5KGluLmRhdGFbLDJdKQ0KICAgaW4ucGN3IDwtIGRlbnNpdHkoaW4uZGF0YVssM10pDQogICBpbi5jZmEgPC0gZGVuc2l0eShpbi5kYXRhWywgNF0pDQogICBkYXQubmFtZSA8LSBzdWIoIlxcLi4qIiwgIiIsbmFtZXMoaW4uZGF0YSlbMV0pICAjc3ViKCB0ZXh0KQ0KICAgIyBwbG90IGRlbnNpdHkgY3VydmVzDQogIGZpZyA8LSBwbG90X2x5KHggPSB+aW4uYXZnJHgsIHkgPSB+aW4uYXZnJHksIA0KICAgICAgICAgICAgICAgdHlwZSA9ICdzY2F0dGVyJywgDQogICAgICAgICAgICAgICBtb2RlID0gJ2xpbmVzJywgDQogICAgICAgICAgICAgICBuYW1lID0gJ2F2ZycsIA0KICAgICAgICAgICAgICAgZmlsbCA9ICd0b3plcm95JykgICU+JSANCiAgICAgICAgICAgIyBhZGRpbmcgbW9yZSBkZW5zaXR5IGN1cnZlcw0KICAgICAgIGFkZF90cmFjZSh4ID0gfmluLnBjMSR4LCB5ID0gfmluLnBjMSR5LCANCiAgICAgICAgICAgICAgICAgbmFtZSA9ICdwY2ExJywgDQogICAgICAgICAgICAgICAgIGZpbGwgPSAndG96ZXJveScpICAlPiUgDQogICAgICAgYWRkX3RyYWNlKHggPSB+aW4ucGN3JHgsIHkgPSB+aW4ucGN3JHksIA0KICAgICAgICAgICAgICAgICBuYW1lID0gJ3BjYS53dCcsIA0KICAgICAgICAgICAgICAgICBmaWxsID0gJ3RvemVyb3knKSAgJT4lIA0KICAgICAgIGFkZF90cmFjZSh4ID0gfmluLmNmYSR4LCB5ID0gfmluLmNmYSR5LCANCiAgICAgICAgICAgICAgICAgbmFtZSA9ICdjZmEnLCANCiAgICAgICAgICAgICAgICAgZmlsbCA9ICd0b3plcm95JykgICU+JSANCiAgICAgICBsYXlvdXQoeGF4aXMgPSBsaXN0KHRpdGxlID0gJ3Njb3JlcycpLA0KICAgICAgICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAnRGVuc2l0eScpLA0KICAgICAgICAgICAgICAjdGl0bGUgPSBkYXQubmFtZSwNCiAgICAgICAgICAgICAgIG1hcmdpbiA9IGxpc3QoDQogICAgICAgICAgICAgICAgICB0ID0gMTAwLCAgIyBBZGp1c3QgdGhpcyB2YWx1ZSB0byBpbmNyZWFzZSBvciBkZWNyZWFzZSB0aGUgdG9wIG1hcmdpbg0KICAgICAgICAgICAgICAgICAgYiA9IDUwLA0KICAgICAgICAgICAgICAgICAgbCA9IDUwLA0KICAgICAgICAgICAgICAgICAgciA9IDUwKQ0KICAgICAgICAgICAgICkNCiAgICAgZmlnDQogICAgIH0NCiMjIyMNCmluLmFueGlldHkubWVhID0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCAiQW54aWV0eS5tZWEuYXZnIiwgIkFueGlldHkubWVhLnBjYTEiLCAiQW54aWV0eS5tZWEud3QucGNhIiwiQW54aWV0eS5tZWEuY2ZhIildDQppbi5hbnhpZXR5Lm1sYSA9IGZpbmFsLmFueGlldHkuZGF0WywgYygiQW54aWV0eS5tbGEuYXZnIiwiQW54aWV0eS5tbGEucGNhMSIsICJBbnhpZXR5Lm1sYS53dC5wY2EiLCJBbnhpZXR5Lm1sYS5jZmEiKV0NCiMjIw0KaW4uYW54aWV0eSA9IGZpbmFsLmFueGlldHkuZGF0WywgYyggIkFueGlldHkuYXZnIiwgIkFueGlldHkucGNhMSIsICJBbnhpZXR5Lnd0LnBjYSIsICJBbnhpZXR5LmNmYSIpXQ0KaW4uZWZmaWNhY3kgPSBmaW5hbC5hbnhpZXR5LmRhdFssIGMoICJTZWxmRWZmaWNhY3kuYXZnIiwgIlNlbGZFZmZpY2FjeS5wY2ExIiwiU2VsZkVmZmljYWN5Lnd0LnBjYSIsIlNlbGZFZmZpY2FjeS5jZmEiKV0NCmluLnRlY2hub2xvZ3kgPSBmaW5hbC5hbnhpZXR5LmRhdFssIGMoICJUZWNobm9sb2d5LmF2ZyIsIlRlY2hub2xvZ3kucGNhMSIsICJUZWNobm9sb2d5Lnd0LnBjYSIsIlRlY2hub2xvZ3kuY2ZhIildDQppbi5jb29wb3JhdGl2ZSA9IGZpbmFsLmFueGlldHkuZGF0WywgYygiQ29vcG9yYXRpdmUuYXZnIiwiQ29vcG9yYXRpdmUucGNhMSIsICJDb29wb3JhdGl2ZS53dC5wY2EiLCJDb29wb3JhdGl2ZS5jZmEiKV0NCmluLmRlZHVjdGl2ZSA9IGZpbmFsLmFueGlldHkuZGF0WywgYygiRGVkdWN0aXZlLmF2ZyIsIkRlZHVjdGl2ZS5wY2ExIiwiRGVkdWN0aXZlLnd0LnBjYSIsIkRlZHVjdGl2ZS5jZmEiKV0NCmluLmRlbW9uc3RyYXRpb24gPSBmaW5hbC5hbnhpZXR5LmRhdFssIGMoIkRlbW9uc3RyYXRpb24uYXZnIiwiRGVtb25zdHJhdGlvbi5wY2ExIiwiRGVtb25zdHJhdGlvbi53dC5wY2EiLCJEZW1vbnN0cmF0aW9uLmNmYSIpXQ0KaW4uaW5kdWN0aXZlID0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCAiSW5kdWN0aXZlLmF2ZyIsIkluZHVjdGl2ZS5wY2ExIiwiSW5kdWN0aXZlLnd0LnBjYSIsIkluZHVjdGl2ZS5jZmEiKV0NCmluLmludGVncmF0aXZlID0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCAiSW50ZWdyYXRpdmUuYXZnIiwgIkludGVncmF0aXZlLnBjYTEiLCJJbnRlZ3JhdGl2ZS53dC5wY2EiLCJJbnRlZ3JhdGl2ZS5jZmEiKV0NCmluLmxlY3R1cmVUeXBlID0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCAiTGVjdHVyZVR5cGUuYXZnIiwgIkxlY3R1cmVUeXBlLnBjYTEiLCAiTGVjdHVyZVR5cGUud3QucGNhIiwiTGVjdHVyZVR5cGUuY2ZhIildDQppbi5yZXBldGl0aXZlID0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCAiUmVwZXRpdGl2ZS5hdmciLCAiUmVwZXRpdGl2ZS5wY2ExIiwgIlJlcGV0aXRpdmUud3QucGNhIiwiUmVwZXRpdGl2ZS5jZmEiKV0NCmluLmVuZ2FnZSA9IGZpbmFsLmFueGlldHkuZGF0WywgYyggICJFbmdhZ2UuYXZnIiwgIkVuZ2FnZS5wY2ExIiwgIkVuZ2FnZS53dC5wY2EiLCJFbmdhZ2UuY2ZhIildDQppbi5yZXNvdXJjZSA9IGZpbmFsLmFueGlldHkuZGF0WywgYyggIlJlc291cmNlLmF2ZyIsICJSZXNvdXJjZS5wY2ExIiwgIlJlc291cmNlLnd0LnBjYSIsICJSZXNvdXJjZS5jZmEiKV0NCmBgYA0KDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9M30NCnAubWVhIDwtIHBsb3RseS5mdW4oaW4uYW54aWV0eS5tZWEpDQpwLm1sYSA8LSBwbG90bHkuZnVuKGluLmFueGlldHkubWxhKQ0KIyBBcnJhbmdlIGluIDF4MiBncmlkDQpzdWJwbG90KHAubWVhLCBwLm1sYSwgbnJvd3MgPSAxLCB0aXRsZVggPSBUUlVFLCB0aXRsZVkgPSBUUlVFLCBtYXJnaW4gPSAwLjEpICU+JQ0KICBsYXlvdXQoDQogICAgYW5ub3RhdGlvbnMgPSBsaXN0KA0KICAgICAgbGlzdCh4ID0gMC4wNSwgeSA9IC45OSwgdGV4dCA9ICJBbnhpZXR5Lm1lYSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuNzUsIHkgPSAwLjk5LCB0ZXh0ID0gIkFueGlldHkubWxhIiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpDQogICAgKSwNCiAgICBzaG93bGVnZW5kID0gRkFMU0UNCiAgKQ0KYGBgDQoNCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD01fQ0KcDEgPC0gcGxvdGx5LmZ1bihpbi5hbnhpZXR5KQ0KcDIgPC0gcGxvdGx5LmZ1bihpbi5lZmZpY2FjeSkNCnAzIDwtIHBsb3RseS5mdW4oaW4udGVjaG5vbG9neSkNCnA0IDwtIHBsb3RseS5mdW4oaW4uY29vcG9yYXRpdmUpDQojIEFycmFuZ2UgaW4gMngyIGdyaWQNCnN1YnBsb3QocDEsIHAyLCBwMiwgcDQsIG5yb3dzID0gMiwgdGl0bGVYID0gVFJVRSwgdGl0bGVZID0gVFJVRSwgbWFyZ2luID0gMC4xKSAlPiUNCiAgbGF5b3V0KA0KICAgIGFubm90YXRpb25zID0gbGlzdCgNCiAgICAgIGxpc3QoeCA9IDAuMDUsIHkgPSAuOTksIHRleHQgPSAiQW54aWV0eSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuNzUsIHkgPSAwLjk5LCB0ZXh0ID0gIlNlbGYtZWZmaWNhY3kiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSksDQogICAgICBsaXN0KHggPSAwLjA1LCB5ID0gMC40LCB0ZXh0ID0gIlRlY2hub2xvZ3kiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSksDQogICAgICBsaXN0KHggPSAwLjc1LCB5ID0gMC40LCB0ZXh0ID0gIkNvb3Jwb3JhdGl2ZSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKQ0KICAgICksDQogICAgc2hvd2xlZ2VuZCA9IEZBTFNFDQogICkNCmBgYA0KDQoNCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD01fQ0KcDEgPC0gcGxvdGx5LmZ1bihpbi5kZWR1Y3RpdmUpDQpwMiA8LSBwbG90bHkuZnVuKGluLmRlbW9uc3RyYXRpb24pDQpwMyA8LSBwbG90bHkuZnVuKGluLmluZHVjdGl2ZSkNCnA0IDwtIHBsb3RseS5mdW4oaW4uaW50ZWdyYXRpdmUpDQojIEFycmFuZ2UgaW4gMngyIGdyaWQNCnN1YnBsb3QocDEsIHAyLCBwMiwgcDQsIG5yb3dzID0gMiwgdGl0bGVYID0gVFJVRSwgdGl0bGVZID0gVFJVRSwgbWFyZ2luID0gMC4xKSAlPiUNCiAgbGF5b3V0KA0KICAgIGFubm90YXRpb25zID0gbGlzdCgNCiAgICAgIGxpc3QoeCA9IDAuMDUsIHkgPSAuOTksIHRleHQgPSAiRGVkdWN0aXZlIiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpLA0KICAgICAgbGlzdCh4ID0gMC43NSwgeSA9IDAuOTksIHRleHQgPSAiRGVtb25zdHJhdGl2ZSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuMDUsIHkgPSAwLjQsIHRleHQgPSAiSW5kdWN0aXZlIiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpLA0KICAgICAgbGlzdCh4ID0gMC43NSwgeSA9IDAuNCwgdGV4dCA9ICJJbnRlcmdyYXRpdmUiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSkNCiAgICApLA0KICAgIHNob3dsZWdlbmQgPSBGQUxTRQ0KICApDQpgYGANCg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTV9DQpwMSA8LSBwbG90bHkuZnVuKGluLmxlY3R1cmVUeXBlKQ0KcDIgPC0gcGxvdGx5LmZ1bihpbi5yZXBldGl0aXZlKQ0KcDMgPC0gcGxvdGx5LmZ1bihpbi5lbmdhZ2UpDQpwNCA8LSBwbG90bHkuZnVuKGluLnJlc291cmNlKQ0KIyBBcnJhbmdlIGluIDJ4MiBncmlkDQpzdWJwbG90KHAxLCBwMiwgcDIsIHA0LCBucm93cyA9IDIsIHRpdGxlWCA9IFRSVUUsIHRpdGxlWSA9IFRSVUUsIG1hcmdpbiA9IDAuMSkgJT4lDQogIGxheW91dCgNCiAgICBhbm5vdGF0aW9ucyA9IGxpc3QoDQogICAgICBsaXN0KHggPSAwLjA1LCB5ID0gLjk5LCB0ZXh0ID0gIkxlY3R1cmUgVHlwZSIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuNzUsIHkgPSAwLjk5LCB0ZXh0ID0gIlJlcGV0YXRpdmUiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSksDQogICAgICBsaXN0KHggPSAwLjA1LCB5ID0gMC40LCB0ZXh0ID0gIkVuZ2FnZW1lbnQiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSksDQogICAgICBsaXN0KHggPSAwLjc1LCB5ID0gMC40LCB0ZXh0ID0gIlJlc291cmNlIiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpDQogICAgKSwNCiAgICBzaG93bGVnZW5kID0gRkFMU0UNCiAgKQ0KYGBgDQoNClRoZXNlIGRlbnNpdHkgY3VydmVzIGlsbHVzdHJhdGUgdGhlIGRpc3RyaWJ1dGlvbnMgb2YgdGhlIGZvdXIgY29tcG9zaXRlIHNjb3JlcyAoKiphdmcsIGNmYSwgcGMxKiosIGFuZCAqKnBjYS53dCoqKSBmb3IgYWxsIHNpbmdsZS1mYWN0b3IgaW5zdHJ1bWVudHMgaW4gdGhlIHN1cnZleS4gVGhlICoqYXZnKiogaXMgYSBuYWl2ZSBtZWFzdXJlLCBkZXJpdmVkIGZyb20gdGhlIGFyaXRobWV0aWMgbWVhbiBvZiB0aGUgaXRlbSBzY29yZXMuIFRoZSAqKmNmYSoqIGFuZCAqKnBjMSoqIGNvbXBvc2l0ZXMgYXJlIHdlaWdodGVkIGF2ZXJhZ2VzLCB3aGVyZSB0aGUgd2VpZ2h0cyAobG9hZGluZ3MpIGFyZSBkZXJpdmVkIGZyb20gZGlzdGluY3QgbGF0ZW50IHZhcmlhYmxlIG1vZGVscy4gVGhlICoqcGNhLnd0IGNvbXBvc2l0KiplIGlzIGEgPGZvbnQgY29sb3I9InJlZCI+Kipkb3VibHkgd2VpZ2h0ZWQgYXZlcmFnZSoqPC9mb250PiwgYmFzZWQgb24gYm90aCB0aGUgb3JpZ2luYWwgaXRlbSBzY29yZXMgYW5kIGFsbCBvZiB0aGUgcmVzdWx0aW5nIHByaW5jaXBhbCBjb21wb25lbnRzLiANCg0KKiBUaHJlZSBtb2RlbC1iYXNlZCBjb21wb3NpdGUgc2NvcmVzICgqKmNmYSwgcGMxKiosIGFuZCAqKnBjYS53dCoqKSBhcmUgY2VudGVyZWQgYXQgMCBidXQgZXhoaWJpdCBkaWZmZXJlbnQgYmVoYXZpb3JzOg0KICArICoqcGMxKiogaGFzIHRoZSBsYXJnZXN0IHZhcmlhbmNlLg0KICArICoqY2ZhKiogaGFzIHRoZSBzbWFsbGVzdCB2YXJpYW5jZS4NCg0KKiAqKmF2ZyoqIGFuZCAqKnBjYS53dCoqIGJlaGF2ZSBzaW1pbGFybHksIGRpZmZlcmluZyBwcmltYXJpbHkgaW4gdGhlaXIgbG9jYXRpb25zLg0KDQpUaGUgY29tcG9zaXRlIHNjb3JlICoqYXZnKiogc2VydmVzIGFzIGEgcmVmZXJlbmNlIHBvaW50LCBhbmFsb2dvdXMgdG8gYW4gZW1waXJpY2FsIGRpc3RyaWJ1dGlvbiwgYXMgaXQgdXNlcyBhbGwgaXRlbSBzY29yZXMgZGlyZWN0bHkuIEluIGNvbnRyYXN0LCAqKnBjYS53dCoqIHVzZXMgYSBkb3VibHkgd2VpZ2h0ZWQgYXZlcmFnZSBvZiBhbGwgaXRlbSBzY29yZXMgd2l0aG91dCBpbXBvc2luZyBjb21wbGV4IGRpc3RyaWJ1dGlvbmFsIGFzc3VtcHRpb25zLiBUaGlzIGRlbW9uc3RyYXRlcyB0aGF0ICoqcGNhLnd0KiogaXMgYSByZWxpYWJsZSBhbmQgcm9idXN0IGNvbXBvc2l0ZSBzY29yZS4gRm9yIHRoZSByZW1haW5kZXIgb2YgdGhpcyByZXBvcnQsIHRoZSAqKnBjYS53dCoqIHNjb3JlIHdpbGwgYmUgdXNlZCwgd2l0aCAqKmNmYSoqIG9jY2FzaW9uYWxseSBlbXBsb3llZCBmb3IgaWxsdXN0cmF0aXZlIHB1cnBvc2VzIGZvciBzb21lIHNwZWNpYWwgY2FzZXMuDQoNCg0KDQojIyBEaXN0cmlidXRpb24gb2YgRGVtb2dyYXBoaWNzDQoNClRoZSBkaXN0cmlidXRpb24gb2YgZGVtb2dyYXBoaWMgZmFjdG9ycyBhcmUgcmVwb3J0ZWQgaW4gdGhlIGZvbGxvd2luZyBmaWd1cmVzLg0KDQpgYGB7cn0NCiMgRW5oYW5jZWQgaG92ZXIgaW5mb3JtYXRpb24NCkRlbW9ncmFwaGljLmJhciA8LWZ1bmN0aW9uKGluLmNhdCwgdmFybmFtZSl7DQogIGZyZXEudGJsIDwtIHRhYmxlKGluLmNhdCkNCiAgZGYgPC0gZGF0YS5mcmFtZSgNCiAgICAgIGNhdGVnb3J5IDwtIG5hbWVzKGZyZXEudGJsKSwNCiAgICAgIHZhbHVlcyA8LSBhcy52ZWN0b3IoZnJlcS50YmwpDQogICkNCiAgIyBIaWdoLWNvbnRyYXN0IGNvbG9ycyAobWFudWFsbHkgZGVmaW5lZCkNCiAgYWNjZXNzaWJsZV9jb2xvcnMgPC0gYygNCiAgJyNENTVFMDAnLCAgIyBWZXJtaWxsaW9uDQogICcjMDA3MkIyJywgICMgQmx1ZQ0KICAnI0YwRTQ0MicsICAjIFllbGxvdw0KICAnIzAwOUU3MycsICAjIEdyZWVuDQogICcjNTZCNEU5JywgICMgU2t5IEJsdWUNCiAgJyNFNjlGMDAnLCAgIyBPcmFuZ2UNCiAgJyNDQzc5QTcnICAgIyBQaW5rDQogICkNCiAgZmlnIDwtIHBsb3RfbHkoZGYsIHggPSB+Y2F0ZWdvcnksIHkgPSB+dmFsdWVzLCB0eXBlID0gJ2JhcicsDQogICAgICAgICAgICAgICAgaG92ZXJpbmZvID0gJ3RleHQnLA0KICAgICAgICAgICAgICAgdGV4dCA9IH5wYXN0ZSgnQ2F0ZWdvcnk6JywgY2F0ZWdvcnksICc8YnI+VmFsdWU6JywgdmFsdWVzLCAnPGJyPlBlcmNlbnRhZ2U6Jywgcm91bmQodmFsdWVzL3N1bSh2YWx1ZXMpKjEwMCwgMSksICclJyksDQogICAgICAgICAgICAgICAjdGV4dCA9IH5wYXN0ZSgiVmFsdWU6IiwgdmFsdWVzKSwgDQogICAgICAgICAgICAgICB0ZXh0cG9zaXRpb24gPSAnYXV0bycsDQogICAgICAgICAgICAgICBtYXJrZXIgPSBsaXN0KA0KICAgICAgICAgICAgICAgICBjb2xvciA9IGFjY2Vzc2libGVfY29sb3JzWzE6bnJvdyhkZildLA0KICAgICAgICAgICAgICAgICBsaW5lID0gbGlzdChjb2xvciA9ICdibGFjaycsIHdpZHRoID0gMikNCiAgICAgICAgICAgICAgICksDQogICAgICAgICAgICAgICB0ZXh0Zm9udCA9IGxpc3QoY29sb3IgPSAnd2hpdGUnLCBzaXplID0gMTIpKSAlPiUNCiAgIGxheW91dCgNCiAgICMgdGl0bGUgPSBsaXN0KHRleHQgPSB2YXJuYW1lLCANCiAgICAgICAgICAgICAgICAjIGZvbnQgPSBsaXN0KHNpemUgPSAxOCwgY29sb3IgPSAnYmxhY2snKSksDQogICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIkNhdGVnb3JpZXMiLCANCiAgICAgICAgICAgICAgICAgdGlja2ZvbnQgPSBsaXN0KGNvbG9yID0gJ2JsYWNrJykpLA0KICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICJWYWx1ZXMiLCANCiAgICAgICAgICAgICAgICAgZ3JpZGNvbG9yID0gJ2xpZ2h0Z3JheScsDQogICAgICAgICAgICAgICAgIHRpY2tmb250ID0gbGlzdChjb2xvciA9ICdibGFjaycpKSwNCiAgICBwbG90X2JnY29sb3IgPSAnd2hpdGUnLA0KICAgIHBhcGVyX2JnY29sb3IgPSAnd2hpdGUnLA0KICAgIHNob3dsZWdlbmQgPSBGQUxTRSwNCiAgICBtYXJnaW4gPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgdCA9IDEwMCwgICMgQWRqdXN0IHRoaXMgdmFsdWUgdG8gaW5jcmVhc2Ugb3IgZGVjcmVhc2UgdGhlIHRvcCBtYXJnaW4NCiAgICAgICAgICAgICAgICAgIGIgPSA1MCwNCiAgICAgICAgICAgICAgICAgIGwgPSA1MCwNCiAgICAgICAgICAgICAgICAgIHIgPSA1MCkNCiAgKQ0KZmlnDQp9DQpgYGANCg0KDQoNCmBgYHtyfQ0KaW4uY2F0LnNleCA8LSAgZmluYWwuYW54aWV0eS5kYXQkc2V4DQppbi5jYXQucmFjZSA8LSAgZmluYWwuYW54aWV0eS5kYXQkcmFjZQ0KaW4uY2F0LmNsYXNzIDwtICBmaW5hbC5hbnhpZXR5LmRhdCRjbGFzcw0KaW4uY2F0Lm1ham9yIDwtICBmaW5hbC5hbnhpZXR5LmRhdCRtYWpvcg0KaW4uY2F0Lm1hdGgubGV2ZWwgPC0gIGZpbmFsLmFueGlldHkuZGF0JG1hdGgubGV2ZWwNCmluLmNhdC5tb2RhbGl0eSA8LSAgZmluYWwuYW54aWV0eS5kYXQkbW9kYWxpdHkNCiMjDQpnLnNleCA8LSBEZW1vZ3JhcGhpYy5iYXIoaW4uY2F0LnNleCwgIkdlbmRlciBEaXN0cmlidXRpb24iKQ0KZy5yYWNlIDwtIERlbW9ncmFwaGljLmJhcihpbi5jYXQucmFjZSwgIlJhY2lhbCBEaXN0cmlidXRpb24iKQ0KZy5jbGFzcyA8LSBEZW1vZ3JhcGhpYy5iYXIoaW4uY2F0LmNsYXNzLCAiQ2xhc3MgRGlzdHJpYnV0aW9uIikNCmcubWFqb3IgPC0gRGVtb2dyYXBoaWMuYmFyKGluLmNhdC5tYWpvciwgIk1ham9yIERpc3RyaWJ1dGlvbiIpDQpnLm1hdGgubGV2ZWwgPC0gRGVtb2dyYXBoaWMuYmFyKGluLmNhdC5tYXRoLmxldmVsLCAiTWF0aCBDb3Vyc2UgTGV2ZWwiKQ0KZy5tb2RhbGl0eSA8LSBEZW1vZ3JhcGhpYy5iYXIoaW4uY2F0Lm1vZGFsaXR5LCAiTGVhcm5pbmcgTW9kYWxpdHkiKQ0KYGBgDQoNCg0KDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9OH0NCiMgQXJyYW5nZSBpbiAyeDIgZ3JpZA0Kc3VicGxvdChnLnNleCwgZy5yYWNlLCBnLmNsYXNzLCBnLm1ham9yLCBucm93cyA9IDIsIHRpdGxlWCA9IEZBTFNFLCB0aXRsZVkgPSBUUlVFLCBtYXJnaW4gPSAwLjEpICU+JQ0KICBsYXlvdXQoDQogICAgYW5ub3RhdGlvbnMgPSBsaXN0KA0KICAgICAgbGlzdCh4ID0gMC4zNSwgeSA9IC45OSwgdGV4dCA9ICJHZW5kZXIiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSksDQogICAgICBsaXN0KHggPSAwLjc1LCB5ID0gMC45OSwgdGV4dCA9ICJSYWNlIiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpLA0KICAgICAgbGlzdCh4ID0gMC4zNSwgeSA9IDAuNCwgdGV4dCA9ICJDbGFzcyBMZXZlbCIsIA0KICAgICAgICAgICB4cmVmID0gInBhcGVyIiwgeXJlZiA9ICJwYXBlciIsIHNob3dhcnJvdyA9IEZBTFNFLCBmb250ID0gbGlzdChzaXplID0gMTQpKSwNCiAgICAgIGxpc3QoeCA9IDAuNzUsIHkgPSAwLjQsIHRleHQgPSAiTWFqb3IiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSkNCiAgICApLA0KICAgIHNob3dsZWdlbmQgPSBGQUxTRQ0KICApDQpgYGANCg0KDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9NH0NCiMgQXJyYW5nZSBpbiAyeDIgZ3JpZA0Kc3VicGxvdChnLm1hdGgubGV2ZWwsIGcubW9kYWxpdHksIG5yb3dzID0gMSwgdGl0bGVYID0gRkFMU0UsIHRpdGxlWSA9IFRSVUUsIG1hcmdpbiA9IDAuMSkgJT4lDQogIGxheW91dCgNCiAgICBhbm5vdGF0aW9ucyA9IGxpc3QoDQogICAgICBsaXN0KHggPSAwLjM1LCB5ID0gLjk5LCB0ZXh0ID0gIk1hdGggQ291cnNlIExldmVsIiwgDQogICAgICAgICAgIHhyZWYgPSAicGFwZXIiLCB5cmVmID0gInBhcGVyIiwgc2hvd2Fycm93ID0gRkFMU0UsIGZvbnQgPSBsaXN0KHNpemUgPSAxNCkpLA0KICAgICAgbGlzdCh4ID0gMC43NSwgeSA9IDAuOTksIHRleHQgPSAiTGVhcm5pbmcgTW9kYWxpdHkiLCANCiAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsIHlyZWYgPSAicGFwZXIiLCBzaG93YXJyb3cgPSBGQUxTRSwgZm9udCA9IGxpc3Qoc2l6ZSA9IDE0KSkNCiAgICApLA0KICAgIHNob3dsZWdlbmQgPSBGQUxTRQ0KICApDQpgYGANCg0KDQpPbmx5IG9uZSBjYXRlZ29yeSBpbiB2YXJpYWJsZSAqKmNsYXNzKiogaXMgbGVzcyB0aGFuIDMlIHdpdGggMjEgb2JzZXJ2YXRpb25zLiBPdGhlciB2YXJpYWJsZXMgZG9uJ3QgaGF2ZSBpc3N1ZXMgb24gc3BhcnNlIGNhdGVnb3JpZXMuDQoNCg0KDQojIyBSZWxhdGlvbnNoaXAgQmV0d2VlbiBNYXRoIEFueGlldHkgYW5kIERlbW9ncmFwaGljIEZhY3RvcnMNCg0KQSBzdHVkZW50J3MgZGVtb2dyYXBoaWMgcHJvZmlsZSBkb2Vzbid0IGRldGVybWluZSB0aGVpciBtYXRoIGFueGlldHksIGJ1dCBpdCBzaWduaWZpY2FudGx5IGluZmx1ZW5jZXMgd2hpY2ggdHlwZSBvZiBhbnhpZXR5IHRoZXkgYXJlIG1vc3QgdnVsbmVyYWJsZSB0byBhbmQgd2h5LiBUaGUgbmV4dCBzdWJzZWN0aW9ucyBwcmVzZW50IHZpc3VhbCBleHBsb3JhdGlvbnMgb2YgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGRlbW9ncmFwaGljIGZhY3RvcnMgYW5kIHRoZSB0d28gZGltZW5zaW9ucyBvZiBtYXRoZW1hdGljYWwgYW54aWV0eS4NCg0KIyMjIE1hdGhlbWF0aWNhbCBFdmFsdWF0aW9uIEFueGlldHkNCg0KVGhpcyBpcyB0aGUgYW54aWV0eSBhIHN0dWRlbnQgZmVlbHMgd2hlbiB0aGVpciBtYXRoZW1hdGljYWwgYWJpbGl0eSBpcyBiZWluZyBmb3JtYWxseSBvciBpbmZvcm1hbGx5IGFzc2Vzc2VkLiBUaGUgcHJpbWFyeSBmZWFyIGlzIG5vdCBvZiB0aGUgbWF0aCBpdHNlbGYsIGJ1dCBvZiB0aGUgbmVnYXRpdmUgY29uc2VxdWVuY2VzIG9mIHBlcmZvcm1pbmcgcG9vcmx5LiBJdCdzIHBlcmZvcm1hbmNlLW9yaWVudGVkLiBUaGUgc3RyZXNzIGNvbWVzIGZyb20gdGhlIHNpdHVhdGlvbiBvZiBiZWluZyBldmFsdWF0ZWQsIG5vdCBuZWNlc3NhcmlseSBmcm9tIHRoZSBjb250ZW50Lg0KDQoNCmBgYHtyfQ0KIyMgcGxvdGx5IGZvciBhbnhpZXR5IHZzIGdlbmRlciBhbmQgb3RoZXIgY2F0ZWdvcmljYWwgZGVtb2dyYXBoaWMgZmFjdG9yDQpnZW5kZXIucGxvdGx5IDwtIGZ1bmN0aW9uKGluLnZhcjEsIGluLnZhcjIpew0KICAgICAgZ2VuZGVyLmFueGlldHkgPC0gcGxvdF9seShmaW5hbC5hbnhpZXR5LmRhdCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gfnNleCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gfkFueGlldHkubWVhLnd0LnBjYSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGFzLmZvcm11bGEocGFzdGUwKCJ+Iixpbi52YXIxKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gImJveCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3hwb2ludHMgPSAibm8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaml0dGVyID0gMC4zLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRwb3MgPSAwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG92ZXJpbmZvID0gInkgKyB4ICsgbmFtZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3ZlcnRleHQgPSB+cGFzdGUoIkdyb3VwOiIsIGluLnZhcjEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPkZhY3RvcjoiLCBzZXgsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPlNjb3JlOiIsIHJvdW5kKEFueGlldHkubWVhLnd0LnBjYSwgMikpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFya2VyID0gbGlzdChzaXplID0gNSwgb3BhY2l0eSA9IDAuNykpICU+JQ0KICAgIGxheW91dCh0aXRsZSA9IHBhc3RlKCJNYXRoIEV2YWx1YXRpb24gQW54aWV0eSAod3QuUENBKTogR2VuZGVyIHZzICIsIGluLnZhcjIsIiIpLA0KICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIiIpLA0KICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIkV2YWx1YXRpb24gQW54aWV0eSBTY29yZSIpLA0KICAgICAgICAgYm94bW9kZSA9ICJncm91cCIsDQogICAgICAgICBob3ZlcmxhYmVsID0gbGlzdChiZ2NvbG9yID0gIndoaXRlIiwgZm9udCA9IGxpc3Qoc2l6ZSA9IDEyKSksDQogICAgICAgICBtYXJnaW4gPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgdCA9IDEwMCwgICMgQWRqdXN0IHRoaXMgdmFsdWUgdG8gaW5jcmVhc2Ugb3IgZGVjcmVhc2UgdGhlIHRvcCBtYXJnaW4NCiAgICAgICAgICAgICAgICAgIGIgPSA1MCwNCiAgICAgICAgICAgICAgICAgIGwgPSA1MCwNCiAgICAgICAgICAgICAgICAgIHIgPSA1MCkNCiAgICAgICAgICkNCg0KIGdlbmRlci5hbnhpZXR5IA0KfQ0KDQpgYGANCg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9DQpnZW5kZXIubWF0aC5sZXZlbCA9IGdlbmRlci5wbG90bHkoIm1hdGgubGV2ZWwiLCAiTWF0aCBDb3Vyc2UgTGV2ZWwiKQ0KZ2VuZGVyLm1hdGgubGV2ZWwNCmBgYA0KDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NH0NCmdlbmRlci5yYWNlID0gZ2VuZGVyLnBsb3RseSgicmFjZSIsICJSYWNlIikNCmdlbmRlci5yYWNlDQpgYGANCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQ0KZ2VuZGVyLmNsYXNzID0gZ2VuZGVyLnBsb3RseSgiY2xhc3MiLCAiQ2xhc3MiKQ0KZ2VuZGVyLmNsYXNzDQpgYGANCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQ0KZ2VuZGVyLm1ham9yID0gZ2VuZGVyLnBsb3RseSgibWFqb3IiLCAiTWFqb3IiKQ0KZ2VuZGVyLm1ham9yDQpgYGANCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQ0KZ2VuZGVyLm1vZGFsaXR5ID0gZ2VuZGVyLnBsb3RseSgibW9kYWxpdHkiLCAiTW9kYWxpdHkiKQ0KZ2VuZGVyLm1vZGFsaXR5DQpgYGANCg0KDQoNClNvbWUgb2YgdGhlIHBhdHRlcm5zIG9ic2VydmVkIGluIHRoaXMgc3R1ZHkgYXJlIGNvbnNpc3RlbnQgd2l0aCB0aGUgZXhpc3RpbmcgbGl0ZXJhdHVyZS4NCg0KKiBGZW1hbGUgc3R1ZGVudHMgaGF2ZSByZWxhdGl2ZWx5IGhpZ2hlciBldmFsdWF0aW9uIGFueGlldHkgbGV2ZWwgdGhhbiBtYWxlIHN0dWRlbnRzLg0KKiBUaGUgZGlzY3JlcGFuY3kgb2YgZXZhbHVhdGlvbiBhbnhpZXR5IGxldmVsIGFjcm9zcyBldGhuaWMgZ3JvdXBzIGFsc28gY29uc2lzdGVudCB3aXRoIHdoYXQgcmVwb3J0ZWQgaW4gdGhlIGV4aXN0aW5nIGxpdGVyYXR1cmUuDQoNCg0KIyMjIE1hdGhlbWF0aWNhbCBMZWFybmluZyBBbnhpZXR5DQoNCk1hdGhlbWF0aWNhbCBsZWFybmluZyBhbnhpZXR5IHN0ZW1zIGRpcmVjdGx5IGZyb20gdGhlIHN1YmplY3QgbWF0dGVyLCB3aGVyZSB0aGUgcHJpbWFyeSBzb3VyY2Ugb2YgZGlzdHJlc3MgaXMgdGhlIGFjdCBvZiBlbmdhZ2luZyB3aXRoIG1hdGhlbWF0aWNhbCBjb25jZXB0cy4gVGhpcyBlbmdhZ2VtZW50IHRyaWdnZXJzIGFuIGludGVybmFsIHN0YXRlIG9mIGNvbmZ1c2lvbiwgZnJ1c3RyYXRpb24sIGFuZCBjb2duaXRpdmUgb3ZlcmxvYWQuDQoNClRoZSBuZXh0IGZldyBmaWd1cmVzIGV4YW1pbmUgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIG1hdGhlbWF0aWNhbCBsZWFybmluZyBhbnhpZXR5IGFuZCBkZW1vZ3JhcGhpYyBmYWN0b3JzLCB1c2luZyB0aGUgc2FtZSB2aXN1YWwgYXBwcm9hY2ggYXMgd2UgZGlkIGZvciBtYXRoZW1hdGljYWwgZXZhbHVhdGlvbiBhbnhpZXR5Lg0KDQoNCmBgYHtyfQ0KIyMgcGxvdGx5IGZvciBhbnhpZXR5IHZzIGdlbmRlciBhbmQgb3RoZXIgY2F0ZWdvcmljYWwgZGVtb2dyYXBoaWMgZmFjdG9yDQpnZW5kZXIucGxvdGx5IDwtIGZ1bmN0aW9uKGluLnZhcjEsIGluLnZhcjIpew0KICAgICAgZ2VuZGVyLmFueGlldHkgPC0gcGxvdF9seShmaW5hbC5hbnhpZXR5LmRhdCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gfnNleCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gfkFueGlldHkubWxhLnd0LnBjYSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGFzLmZvcm11bGEocGFzdGUwKCJ+Iixpbi52YXIxKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gImJveCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3hwb2ludHMgPSAibm8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaml0dGVyID0gMC4zLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRwb3MgPSAwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG92ZXJpbmZvID0gInkgKyB4ICsgbmFtZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3ZlcnRleHQgPSB+cGFzdGUoIkdyb3VwOiIsIGluLnZhcjEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPkZhY3RvcjoiLCBzZXgsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPlNjb3JlOiIsIHJvdW5kKEFueGlldHkubWxhLnd0LnBjYSwgMikpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFya2VyID0gbGlzdChzaXplID0gNSwgb3BhY2l0eSA9IDAuNykpICU+JQ0KICAgIGxheW91dCh0aXRsZSA9IHBhc3RlKCJNYXRoIExlYXJuaW5nIEFueGlldHkgKHd0LlBDQSk6IEdlbmRlciB2cyAiLCBpbi52YXIyLCIiKSwNCiAgICAgICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICIiKSwNCiAgICAgICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICJMZWFybmluZyBBbnhpZXR5IFNjb3JlIiksDQogICAgICAgICBib3htb2RlID0gImdyb3VwIiwNCiAgICAgICAgIGhvdmVybGFiZWwgPSBsaXN0KGJnY29sb3IgPSAid2hpdGUiLCBmb250ID0gbGlzdChzaXplID0gMTIpKSwNCiAgICAgICAgIG1hcmdpbiA9IGxpc3QoDQogICAgICAgICAgICAgICAgICB0ID0gMTAwLCAgIyBBZGp1c3QgdGhpcyB2YWx1ZSB0byBpbmNyZWFzZSBvciBkZWNyZWFzZSB0aGUgdG9wIG1hcmdpbg0KICAgICAgICAgICAgICAgICAgYiA9IDUwLA0KICAgICAgICAgICAgICAgICAgbCA9IDUwLA0KICAgICAgICAgICAgICAgICAgciA9IDUwKQ0KICAgICAgICAgKQ0KDQogZ2VuZGVyLmFueGlldHkgDQp9DQoNCmBgYA0KDQoNCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQ0KZ2VuZGVyLm1hdGgubGV2ZWwubWxhID0gZ2VuZGVyLnBsb3RseSgibWF0aC5sZXZlbCIsICJNYXRoIENvdXJzZSBMZXZlbCIpDQpnZW5kZXIubWF0aC5sZXZlbC5tbGENCmBgYA0KDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NH0NCmdlbmRlci5yYWNlLm1sYSA9IGdlbmRlci5wbG90bHkoInJhY2UiLCAiUmFjZSIpDQpnZW5kZXIucmFjZS5tbGENCmBgYA0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9DQpnZW5kZXIuY2xhc3MubWxhID0gZ2VuZGVyLnBsb3RseSgiY2xhc3MiLCAiQ2xhc3MiKQ0KZ2VuZGVyLmNsYXNzLm1sYQ0KYGBgDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NH0NCmdlbmRlci5tYWpvci5tbGEgPSBnZW5kZXIucGxvdGx5KCJtYWpvciIsICJNYWpvciIpDQpnZW5kZXIubWFqb3IubWxhDQpgYGANCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQ0KZ2VuZGVyLm1vZGFsaXR5Lm1sYSA9IGdlbmRlci5wbG90bHkoIm1vZGFsaXR5IiwgIk1vZGFsaXR5IikNCmdlbmRlci5tb2RhbGl0eS5tbGENCmBgYA0KDQoNCiMjIFRoZSBHZW5kZXIgR2FwIGluIEV2YWx1YXRpb24gYW5kIExlYXJuaW5nIEFueGlldHkNCg0KSXQgdHVybnMgb3V0IHRoYXQsIGNvbXBhcmluZyB0byBtYXRoIGxlYXJuaW5nIGFueGlldHksIGV2YWx1YXRpb24gYW54aWV0eSBtYW5pZmVzdHMgdGhlIGdlbmRlciBnYXAuIFRoaXMgb2JzZXJ2YXRpb24gaXMgc3VwcG9ydGVkIGJ5IGFjYWRlbWljIHJlc2VhcmNoLiBUaGUga2V5IGluc2lnaHQgaXMgdGhhdCB0aGUgZ2VuZGVyIGdhcCBpbiBtYXRoIHBlcmZvcm1hbmNlIGlzIG1vcmUgc3Ryb25nbHkgbGlua2VkIHRvIHRoZSBhbnhpZXR5IGdlbmVyYXRlZCBieSB0aGUgdGVzdGluZyBzaXR1YXRpb24gdGhhbiBieSBhbnhpZXR5IHRvd2FyZCB0aGUgc3ViamVjdCBtYXR0ZXIgaXRzZWxmIChsZWFkaW5nIHBvdGVudGlhbCBsZWFybmluZyBhbnhpZXR5KS4NCg0KQSByb2J1c3QgYm9keSBvZiBldmlkZW5jZSwgZnJvbSBmb3VuZGF0aW9uYWwgbWV0YS1hbmFseXNlcyAoSGVtYnJlZSwgMTk5MCkgdG8gY29udGVtcG9yYXJ5IHN0dWRpZXMgKERldmluZSBldCBhbC4sIDIwMTI7IEdvZXR6IGV0IGFsLiwgMjAxMyksIGVzdGFibGlzaGVzIHRoYXQgZmVtYWxlIHN0dWRlbnRzIGV4cGVyaWVuY2UgZGlzcHJvcG9ydGlvbmF0ZWx5IGhpZ2ggbGV2ZWxzIG9mIG1hdGggdGVzdCBhbnhpZXR54oCUYSBmYWN0b3IgbW9yZSBwcmVkaWN0aXZlIG9mIGFjYWRlbWljIG91dGNvbWVzIHRoYW4gbGVhcm5pbmcgYW54aWV0eS4gVGhpcyBmaW5kaW5nIGlsbHVtaW5hdGVzIHRoZSB3b3JrIG9mIEVsc2UtUXVlc3QgZXQgYWwuICgyMDEwKSwgZGVtb25zdHJhdGluZyB0aGF0IHRoZSBnZW5kZXIgZ2FwIGluIG1hdGggcGVyZm9ybWFuY2UgaXMgcHJvZm91bmRseSBzaGFwZWQgYnkgYW54aWV0eSBpbiBldmFsdWF0aXZlIGVudmlyb25tZW50cy4gVGhlcmVmb3JlLCBhZGRyZXNzaW5nIHRoZSBzcGVjaWZpYyBwcmVzc3VyZXMgb2YgdGVzdGluZyBzaXR1YXRpb25zIGlzIGVzc2VudGlhbCBmb3IgY2xvc2luZyB0aGlzIGdhcC4NCg0KVGhlIGZvbGxvd2luZyBmaWd1cmUgaWxsdXN0cmF0ZXMgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGdlbmRlciBhbmQgdGhlIHR3byB0eXBlcyBvZiBtYXRoIGFueGlldHk6IGxlYXJuaW5nIGFueGlldHkgYW5kIGV2YWx1YXRpb24gYW54aWV0eS4NCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD02fQ0KbWVhMCA8LSBmaW5hbC5hbnhpZXR5LmRhdFssIGMoInNleCIsICJBbnhpZXR5Lm1lYS53dC5wY2EiKV0NCm1sYTAgPC0gZmluYWwuYW54aWV0eS5kYXRbLCBjKCJzZXgiLCAiQW54aWV0eS5tbGEud3QucGNhIildDQpuYW1lcyhtZWEwKSA9IGMoInNleCIsICJhbnhpZXR5LnNjb3JlIikNCm5hbWVzKG1sYTApID0gYygic2V4IiwgImFueGlldHkuc2NvcmUiKQ0KbWVhLm1sYSA8LSByYmluZChtZWEwLCBtbGEwKQ0KYW54aWV0eS50eXBlIDwtIGMocmVwKCJtZWEiLCBkaW0obWVhMClbMV0pLCByZXAoIm1sYSIsIGRpbShtZWEwKVsxXSkpDQptZWEubWxhJGFueGlldHkudHlwZSA8LSBhbnhpZXR5LnR5cGUNCiMjIyMNCmRmID0gbmEub21pdChtZWEubWxhKQ0KIyBDcmVhdGUgbW9yZSBjb21wbGV4IGdyb3VwZWQgYm94cGxvdCB3aXRoIHN0YXRpc3RpY2FsIGFubm90YXRpb25zDQojIEN1c3RvbSBob3ZlciBpbmZvcm1hdGlvbg0KZmlnIDwtIHBsb3RfbHkoZGYsIA0KICAgICAgICAgICAgICAgeCA9IH5hbnhpZXR5LnR5cGUsIA0KICAgICAgICAgICAgICAgeSA9IH5hbnhpZXR5LnNjb3JlLCANCiAgICAgICAgICAgICAgIGNvbG9yID0gfnNleCwNCiAgICAgICAgICAgICAgIHR5cGUgPSAiYm94IiwNCiAgICAgICAgICAgICAgIGhvdmVyaW5mbyA9ICJ5K3grbmFtZSIsDQogICAgICAgICAgICAgICBob3ZlcnRlbXBsYXRlID0gcGFzdGUoDQogICAgICAgICAgICAgICAgICJHZW5kZXI6ICV7eH08YnI+IiwNCiAgICAgICAgICAgICAgICAgIkFueGlldHkgVHlwZTogJXtmdWxsRGF0YS5uYW1lfTxicj4iLA0KICAgICAgICAgICAgICAgICAiQW54aWV0eSBTY29yZTogJXt5Oi4yZn08YnI+IiwNCiAgICAgICAgICAgICAgICAgIjxleHRyYT48L2V4dHJhPiINCiAgICAgICAgICAgICAgICkpICU+JQ0KICBsYXlvdXQoDQogICAgdGl0bGUgPSAiR2VuZGVyIERpc3Bhcml0aWVzIGluIE1hdGggRXZhbHVhdGlvbiBhbmQgTGVhcm5pbmcgQW54aWV0eSIsDQogICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIiIpLA0KICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICJBbnhpZXR5IFNjb3JlIiksDQogICAgYm94bW9kZSA9ICJncm91cCIsDQogICAgaG92ZXJsYWJlbCA9IGxpc3QoYmdjb2xvciA9ICJ3aGl0ZSIsIGZvbnQgPSBsaXN0KHNpemUgPSAxMikpLA0KICAgIG1hcmdpbiA9IGxpc3QoIHQgPSAxMDAsICAjIEFkanVzdCB0aGlzIHZhbHVlIHRvIGluY3JlYXNlIG9yIGRlY3JlYXNlIHRoZSB0b3AgbWFyZ2luDQogICAgICAgICAgICAgICAgICBiID0gNTAsDQogICAgICAgICAgICAgICAgICBsID0gNTAsDQogICAgICAgICAgICAgICAgICByID0gNTApDQogICkNCg0KZmlnDQoNCmBgYA0KDQpPdXIgcmVzdWx0cyBhcmUgYWxzbyBjb25zaXN0ZW50IHdpdGggZXhpc3RpbmcgcmVzdWx0cyBpbiBsaXRlcmF0dXJlLg0KDQoNCiMgU3R1ZGVudCBQZXJjZWl2ZWQgVGVhY2hpbmcgU3RyYXRlZ2llcyBhbmQgTWF0aCBBbnhpZXR5DQoNCk1hdGggYW54aWV0eSBpcyBvZnRlbiBleGFjZXJiYXRlZCBieSBhIGRpc2Nvbm5lY3QgYmV0d2VlbiBhIHN0dWRlbnQncyBjb2duaXRpdmUgbmVlZHMgYW5kIHRoZSBpbnN0cnVjdG9yJ3MgcHJlZG9taW5hbnQgcGVkYWdvZ2ljYWwgYXBwcm9hY2guIFRvIG1pdGlnYXRlIHRoaXMsIGEgcHJvYWN0aXZlIG1ldGhvZCBpbnZvbHZlcyBsZXZlcmFnaW5nIHN0dWRlbnRzJyBwZXJjZXB0aW9ucyBvZiB0ZWFjaGluZyBzdHJhdGVnaWVzLiANCg0KIyMgSGVhdG1hcCBvZiBQYWlyd2lzZSBDb3JyZWxhdGlvbnMNCg0KVGhlIGZvbGxvd2luZyBoZWF0bWFwIGlsbHVzdHJhdGVzIHRoZSBwYWlyd2lzZSBjb3JyZWxhdGlvbnMgYmV0d2VlbiBhbnhpZXR5IGxldmVscywgc3R1ZGVudC1wZXJjZWl2ZWQgdGVhY2hpbmcgc3RyYXRlZ2llcywgYW5kIG90aGVyIGFzc29jaWF0ZWQgY29nbml0aXZlIGZhY3RvcnMuIEEgbmVnYXRpdmUgY29ycmVsYXRpb24gYmV0d2VlbiBhbnhpZXR5IGFuZCBhbm90aGVyIGNvbXBvc2l0ZSBzY29yZSAoc2hvd24gaW4gYmx1ZSkgaW5kaWNhdGVzIHRoYXQgYW54aWV0eSBkZWNyZWFzZXMgYXMgdGhhdCBjb21wb3NpdGUgc2NvcmUgaW5jcmVhc2VzLg0KDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nn0NCg0KdmFyLm5hbWUgPC1jKCAiQW54aWV0eS5tZWEud3QucGNhIiwgIkFueGlldHkubWxhLnd0LnBjYSIsICJTZWxmRWZmaWNhY3kud3QucGNhIiwgIlRlY2hub2xvZ3kud3QucGNhIiwNCiAgICAgICAgICAgICAgIkNvb3BvcmF0aXZlLnd0LnBjYSIsICJEZWR1Y3RpdmUud3QucGNhIiwgIkRlbW9uc3RyYXRpb24ud3QucGNhIiwNCiAgICAgICAgICAgICAgIkluZHVjdGl2ZS53dC5wY2EiLCAiSW50ZWdyYXRpdmUud3QucGNhIiwgIkxlY3R1cmVUeXBlLnd0LnBjYSIsDQogICAgICAgICAgICAgICJSZXBldGl0aXZlLnd0LnBjYSIsICJFbmdhZ2Uud3QucGNhIiwgIlJlc291cmNlLnd0LnBjYSIpDQphbGwuY29tcG9zaXRlLnNjb3JlcyA8LSBmaW5hbC5hbnhpZXR5LmRhdFssIHZhci5uYW1lXQ0KbmFtZXMoYWxsLmNvbXBvc2l0ZS5zY29yZXMpIDwtIGMoICJBbnhpZXR5Lm1lYSIsICJBbnhpZXR5Lm1sYSIsICJTZWxmRWZmaWNhY3kiLCAiVGVjaG5vbG9neSIsDQogICAgICAgICAgICAgICJDb29wb3JhdGl2ZSIsICJEZWR1Y3RpdmUuIiwgIkRlbW9uc3RyYXRpb24iLA0KICAgICAgICAgICAgICAiSW5kdWN0aXZlIiwgIkludGVncmF0aXZlIiwgIkxlY3R1cmVUeXBlIiwNCiAgICAgICAgICAgICAgIlJlcGV0aXRpdmUiLCAiRW5nYWdlIiwgIlJlc291cmNlLiIpDQoNCiMgQ2FsY3VsYXRlIGNvcnJlbGF0aW9uIG1hdHJpeA0KY29yX21hdHJpeCA8LSBjb3IoYWxsLmNvbXBvc2l0ZS5zY29yZXMsIHVzZSA9ICJjb21wbGV0ZS5vYnMiKQ0KDQojIENvbnZlcnQgdG8gbG9uZyBmb3JtYXQgdXNpbmcgbWVsdA0KY29yX2xvbmcgPC0gbWVsdChjb3JfbWF0cml4KQ0KbmFtZXMoY29yX2xvbmcpIDwtIGMoIngiLCAieSIsICJyIikNCg0KIyBSZW1vdmUgc2VsZi1jb3JyZWxhdGlvbnMgYW5kIHVwcGVyIHRyaWFuZ2xlIGlmIGRlc2lyZWQNCmNvcl9sb25nIDwtIGNvcl9sb25nW2Nvcl9sb25nJHggIT0gY29yX2xvbmckeSwgXQ0KDQojIENyZWF0ZSBpbnRlcmFjdGl2ZSBoZWF0bWFwDQpwbG90X2x5KGNvcl9sb25nLCB4ID0gfngsIHkgPSB+eSwgeiA9IH5yLCB0eXBlID0gImhlYXRtYXAiLA0KICAgICAgICBjb2xvcnNjYWxlID0gIlJkQnUiLCB6bWluID0gLTEsIHptYXggPSAxLA0KICAgICAgICBob3ZlcmluZm8gPSAidGV4dCIsDQogICAgICAgIHRleHQgPSB+cGFzdGUoIlg6IiwgeCwgIjxicj5ZOiIsIHksICI8YnI+ciA9Iiwgcm91bmQociwgMykpKSAlPiUNCiAgbGF5b3V0KHRpdGxlID0gIkNvcnJlbGF0aW9uIE1hdHJpeCIsDQogICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiIiksDQogICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiIiksDQogICAgICAgICBtYXJnaW4gPSBsaXN0KGwgPSAxMDAsIHIgPSA1MCwgYiA9IDEwMCwgdCA9IDUwKSkNCmBgYA0KDQpUaGUgZmlndXJlIGFib3ZlIHNob3dzIHRoYXQgYWxsIHBlcmNlaXZlZCB0ZWFjaGluZyBzdHJhdGVnaWVzIGFyZSBuZWdhdGl2ZWx5IGNvcnJlbGF0ZWQgd2l0aCBib3RoIHR5cGVzIG9mIGFueGlldHkuIEluIGFkZGl0aW9uLCBzdHVkZW50cyB3aXRoIGhpZ2ggbGV2ZWxzIG9mIHNlbGYtZWZmaWNhY3kgdGVuZCB0byBoYXZlIGxvdyBsZXZlbHMgb2YgbWF0aCBhbnhpZXR5LiBGdXJ0aGVybW9yZSwgdGhlIGNvbXBvc2l0ZSBzY29yZSBmb3IgdGVjaG5vbG9neSB1c2UgaXMgbmVnYXRpdmVseSBjb3JyZWxhdGVkIHdpdGggYm90aCBsZWFybmluZyBhbmQgZXZhbHVhdGlvbiBhbnhpZXR5LCBpbXBseWluZyB0aGF0IHRlY2hub2xvZ3kgY2FuIGhlbHAgcmVkdWNlIG1hdGggYW54aWV0eS4gQ29udmVyc2VseSwgd2UgYWxzbyBzZWUgdGhhdCBzdHVkZW50cyB3aG8gdXNlIG1vcmUgbGVhcm5pbmcgcmVzb3VyY2VzIHRlbmQgdG8gaGF2ZSBoaWdoZXIgbGVhcm5pbmcgYW54aWV0eS4NCg0KDQpBcyB0aGUgcmVkIGJsb2NrIGluIHRoZSBjZW50ZXIgb2YgdGhlIGhlYXRtYXAgaW5kaWNhdGVzLCBhbGwgdGVhY2hpbmcgc3RyYXRlZ2llcyBhcmUgcG9zaXRpdmVseSBjb3JyZWxhdGVkLiBUaGlzIGNvbGxpbmVhcml0eSBtYXkgcG9zZSBhIHByb2JsZW0gZm9yIHN1YnNlcXVlbnQgcmVncmVzc2lvbiBhbmFseXNpcy4gV2Ugd2lsbCBhZGRyZXNzIHRoaXMgY29uY2VybiBpbiB0aGUgZm9sbG93aW5nIHNlY3Rpb24uDQoNCg0KIyMgR3JvdXBpbmcgVGVhY2hpbmcgU3RyYXRlZ2llcw0KDQoNClRoZSBmb2xsb3dpbmcgZGVuc2l0eSBjdXJ2ZXMgcmVwcmVzZW50ICpuYWl2ZSogY29tcG9zaXRlIHNjb3JlcyBkZXJpdmVkIGZyb20gdGhlIGF2ZXJhZ2Ugb2YgaXRlbSBzY29yZXMgZm9yIGVhY2ggb2YgdGhlIHNldmVuIHRlYWNoaW5nIHN0cmF0ZWdpZXMuIFRoZXNlIGN1cnZlcyBpbGx1c3RyYXRlIHRoZSBzdHVkZW50cycgcGVyY2VwdGlvbnMgb2YgdGhlaXIgaW5zdHJ1Y3RvcnMnIHRlYWNoaW5nIHN0cmF0ZWdpZXMuIEEgaGlnaGVyIHNjb3JlIGluZGljYXRlcyB0aGF0IHN0dWRlbnRzIHdlcmUgbW9yZSBsaWtlbHkgdG8gcGVyY2VpdmUgdGhlIHVzZSBvZiB0aGF0IHN0cmF0ZWd5Lg0KDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Niwgd2FybmluZyA9IEZBTFNFfQ0KdmFyLm5hbWUgPC1jKCAiQ29vcG9yYXRpdmUuYXZnIiwgIkRlZHVjdGl2ZS5hdmciLCAiRGVtb25zdHJhdGlvbi5hdmciLA0KICAgICAgICAgICAgICAiSW5kdWN0aXZlLmF2ZyIsICJJbnRlZ3JhdGl2ZS5hdmciLCAiTGVjdHVyZVR5cGUuYXZnIiwNCiAgICAgICAgICAgICAgIlJlcGV0aXRpdmUuYXZnIikNCmFsbC5jb21wb3NpdGUuc2NvcmVzIDwtIGZpbmFsLmFueGlldHkuZGF0WywgdmFyLm5hbWVdDQpuYW1lcyhhbGwuY29tcG9zaXRlLnNjb3JlcykgPC0gYygiQ29vcGVyYXRpdmUiLCAiRGVkdWN0aXZlIiwgIkRlbW9uc3RyYXRpdmUiLA0KICAgICAgICAgICAgICAiSW5kdWN0aXZlIiwgIkludGVncmF0aXZlIiwgIkxlY3R1cmUiLCAgICJSZXBldGl0aXZlIikNCg0KIyBGb3Igb2xkZXIgdmVyc2lvbnMgb2YgdGlkeXINCmxvbmdfZGF0YSA8LSBhbGwuY29tcG9zaXRlLnNjb3JlcyAlPiUNCiAgcGl2b3RfbG9uZ2VyKA0KICAgIGNvbHMgPSBjKCBDb29wZXJhdGl2ZSwgRGVkdWN0aXZlLCBEZW1vbnN0cmF0aXZlLCBJbmR1Y3RpdmUsIEludGVncmF0aXZlLCBMZWN0dXJlLCBSZXBldGl0aXZlKSwgICMgQ29sdW1ucyB0byByZXNoYXBlDQogICAgbmFtZXNfdG8gPSAidmFyaWFibGUiLCAgICAgICAgICAjIE5ldyBjb2x1bW4gbmFtZSBmb3IgdmFyaWFibGUgbmFtZXMNCiAgICB2YWx1ZXNfdG8gPSAidmFsdWUiICAgICAgICAgICAgICMgTmV3IGNvbHVtbiBuYW1lIGZvciB2YWx1ZXMNCiAgKQ0KDQojIyBTdW1tYXJpemVkIHN0YXRzDQoNCnN1bW1hcnlfc3RhdHMgPC0gbG9uZ19kYXRhICU+JQ0KICBncm91cF9ieSh2YXJpYWJsZSkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBtZWFuX3ZhbCA9IG1lYW4odmFsdWUpLA0KICAgIG1lZGlhbl92YWwgPSBtZWRpYW4odmFsdWUpLA0KICAgIHNkX3ZhbCA9IHNkKHZhbHVlKSwNCiAgICBuID0gbigpLA0KICAgIC5ncm91cHMgPSAnZHJvcCcNCiAgKQ0KDQojIENyZWF0ZSByaWRnZSBwbG90IHdpdGggZ2dyaWRnZXMgYW5kIGNvbnZlcnQgdG8gcGxvdGx5DQpyaWRnZV9nZyA8LSBnZ3Bsb3QobG9uZ19kYXRhLCBhZXMoeCA9IHZhbHVlLCB5ID0gdmFyaWFibGUsIGZpbGwgPSB2YXJpYWJsZQ0KICApKSArDQogIGdlb21fZGVuc2l0eV9yaWRnZXMoDQogICAgYWxwaGEgPSAwLjcsDQogICAgc2NhbGUgPSAyLCAgIyBBZGp1c3Qgb3ZlcmxhcA0KICAgIGNvbG9yID0gIndoaXRlIiwNCiAgICBzaXplID0gMC41LA0KICAgICApICsNCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikgKw0KICAjdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDApKSArDQogIHRoZW1lX3JpZGdlcygpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJEaXN0cmlidXRpb25zIG9mIFN0dWRlbnRzJyBQZXJjZWl2ZWQgXG4gVGVhY2hpbmcgU3RyYXRlZ3kgSW5kaWNlcyIsDQogICAgeCA9ICJQZXJjZWl2ZWQgVGVhY2hpbmcgU3RyYXRlZ3kgU2NvcmUiLA0KICAgIHkgPSAiIg0KICApICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwNCiAgICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4odCA9IDEuMiwgdW5pdCA9ICJjbSIpKQ0KDQojIENvbnZlcnQgdG8gcGxvdGx5DQpnZ3Bsb3RseShyaWRnZV9nZykNCmBgYA0KDQoNCkFzIHNob3duIGluIHRoZSBmaWd1cmUsIHRoZSAqKnJlcGV0aXRpdmUqKiwgKipsZWN0dXJlLXR5cGUqKiwgKippbmR1Y3RpdmUqKiwgYW5kICoqZGVtb25zdHJhdGl2ZSoqIGFwcHJvYWNoZXMgd2VyZSBwZXJjZWl2ZWQgYXMgbW9yZSBwb3B1bGFyIHRoYW4gdGhlICoqaW50ZWdyYXRpdmUqKiwgKipkZWR1Y3RpdmUqKiwgYW5kICoqY29vcGVyYXRpdmUqKiBhcHByb2FjaGVzLiBUaGlzIG9ic2VydmF0aW9uIGFsaWducyB3aXRoIHRoZSBlc3RhYmxpc2hlZCBjbGFzc2lmaWNhdGlvbiBvZiB0ZWFjaGluZyBzdHlsZXMgaW4gZWR1Y2F0aW9uYWwgYW5kIHBzeWNob2xvZ2ljYWwgcmVzZWFyY2ggYW5kIGNsYXNzaWMgdGV4dGJvb2tzLg0KDQoNCnwgICAgVGVhY2hlci1jZW50ZXJlZCB8ICAgU3R1ZGVudC1jZW50ZXJlZCB8DQp8Oi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXw6LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18DQp8ICoqRGVkdWN0aXZlKiogKFRlYWNoZXIgcHJvdmlkZXMgcnVsZXMgYW5kIGV4YW1wbGVzOiBKb3ljZSBldCBhbC4sIDIwMTUpIHwJKipDb29wZXJhdGl2ZSoqIChTdHVkZW50cyB3b3JrIHRvZ2V0aGVyOiBKb2huc29uLCAyMDE0KXwNCnwgKipMZWN0dXJlIFR5cGUqKiAoVGVhY2hlciB0cmFuc21pdHMgaW5mb3JtYXRpb246IEJyb3duLDIwMDcpIHwJCSoqSW5kdWN0aXZlKiogKFN0dWRlbnRzIGRpc2NvdmVyIHJ1bGVzOiBCcnVuZXIsIDE5NjE7IFByaW5jZSAgJiBGZWxkZXIsIDIwMDYpfA0KfCAqKkRlbW9uc3RyYXRpb24qKiAoVGVhY2hlciBzaG93cyBob3c6IEJvcmljaCwgMjAxNykgfAkJKipJbnRlZ3JhdGl2ZSoqIChTdHVkZW50cyBjb25uZWN0IGlkZWFzOiBKYWNvYnMsIDE5ODk7IEZvZ2FydHksMTk5MSl8DQp8ICoqUmVwZXRpdGl2ZSoqIChUZWFjaGVyIGRyaWxscyB0aGUgaW5mb3JtYXRpb246IE9ybXJvZCwgMjAyMCkgfAkgIHwNCg0KVGhlIGFib3ZlIGNsYXNzaWZpY2F0aW9uIGlzIGNvbnNpc3RlbnQgd2l0aCB0aGUgb25lIGJhc2VkIG9uIGNvZ25pdGl2ZSBkZW1hbmQgKEJsb29tJ3MgVGF4b25vbXkpLCB3aGljaCBjYXRlZ29yaXplcyBzdHJhdGVnaWVzIGFzIHJlcXVpcmluZyBlaXRoZXIgbG93ZXItbGV2ZWwgdGhpbmtpbmcgKHJlbWVtYmVyLCB1bmRlcnN0YW5kKSBvciBoaWdoZXItbGV2ZWwgdGhpbmtpbmcgKGFwcGx5LCBhbmFseXplLCBldmFsdWF0ZSwgY3JlYXRlKS4gVA0KDQoNClRoaXMgY2xhc3NpZmljYXRpb24gZGVtb25zdHJhdGVzIGEgc3BlY3RydW0gb2YgcGVkYWdvZ2ljYWwgYXBwcm9hY2hlcywgZnJvbSB0cmFkaXRpb25hbCwgaGlnaGx5IHN0cnVjdHVyZWQgbWV0aG9kcyBsaWtlIExlY3R1cmUgYW5kIERlZHVjdGl2ZSB0ZWFjaGluZywgdG8gbW9kZXJuLCBzdHVkZW50LWRyaXZlbiBtZXRob2RzIGxpa2UgSW5kdWN0aXZlLCBDb29wZXJhdGl2ZSwgYW5kIEludGVncmF0aXZlIGxlYXJuaW5nLiBEZW1vbnN0cmF0aW9uIGFuZCBSZXBldGl0aXZlIHByYWN0aWNlIHNlcnZlIHNwZWNpZmljLCBvZnRlbiBjb21wbGVtZW50YXJ5LCByb2xlcyB3aXRoaW4gdGhpcyBzcGVjdHJ1bS4NCg0KDQojIyBDcmVhdGUgU2luZ2xlIENvbXBvc2l0ZSBTY29yZSBmb3IgdGhlIENsYXNzaWZpY2F0aW9uDQoNCldlIG5leHQgZGVmaW5lIHR3byBzaW5nbGUgaW5kaWNlcyB0byByZXByZXNlbnQgdGhlIHRlYWNoaW5nIHN0cmF0ZWdpZXMgYmFzZWQgb24gdGhlIGFib3ZlIGNsYXNzaWZpY2F0aW9uLiBXZSBjb25jZXB0dWFsaXplIHRlYWNoZXItY2VudGVyZWQgYW5kIHN0dWRlbnQtY2VudGVyZWQgc3RyYXRlZ2llcyBhcyB0d28gc2luZ2xlLWZhY3RvciBjb25zdHJ1Y3RzLiBUaGUgaW5kaWNlcyBhcmUgZGVmaW5lZCB1c2luZyBhIGRvdWJseSB3ZWlnaHRlZCBhdmVyYWdlIG9mIHRoZSBwcmluY2lwYWwgY29tcG9uZW50cy4gRm9sbG93aW5nIGNvbW1vbiBwcmFjdGljZSwgd2UgcmVwb3J0IHRoZSB2YWxpZGl0eSBhbmQgcmVsaWFiaWxpdHkgbWVhc3VyZXMgYmVmb3JlIGNhbGN1bGF0aW5nIHRoZSBjb21wb3NpdGUgc2NvcmVzIGZvciB0aGUgdHdvIGNsYXNzaWZpZWQgdGVhY2hpbmcgc3RyYXRlZ2llcy4NCg0KKipWYWxpZGl0eSBNZWFzdXJlcyoqDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCBldmFsID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KdmFyLm5hbWUgPC1jKCJDb29wb3JhdGl2ZS5jZmEiLCAiRGVkdWN0aXZlLmNmYSIsICJEZW1vbnN0cmF0aW9uLmNmYSIsDQogICAgICAgICAgICAgICJJbmR1Y3RpdmUuY2ZhIiwgIkludGVncmF0aXZlLmNmYSIsICJMZWN0dXJlVHlwZS5jZmEiLA0KICAgICAgICAgICAgICAiUmVwZXRpdGl2ZS5jZmEiKQ0KU3RyYXRlZ2Uud3QucGNhIDwtIGZpbmFsLmFueGlldHkuZGF0WywgdmFyLm5hbWVdDQpuYW1lcyhTdHJhdGVnZS53dC5wY2EpIDwtIGMoIkNvb3BlcmF0aXZlIiwgIkRlZHVjdGl2ZSIsICJEZW1vbnN0cmF0aXZlIiwNCiAgICAgICAgICAgICAgIkluZHVjdGl2ZSIsICJJbnRlZ3JhdGl2ZSIsICJMZWN0dXJlIiwgICAiUmVwZXRpdGl2ZSIpDQoNCg0KDQp0ZWFjaGVyMCA8LSBTdHJhdGVnZS53dC5wY2FbLGMoIkRlZHVjdGl2ZSIsICJEZW1vbnN0cmF0aXZlIiwgIkxlY3R1cmUiLCAiUmVwZXRpdGl2ZSIpXQ0Kc3R1ZGVudDAgPC0gU3RyYXRlZ2Uud3QucGNhWyxjKCJDb29wZXJhdGl2ZSIsICJJbmR1Y3RpdmUiLCAiSW50ZWdyYXRpdmUiLCAiRGVkdWN0aXZlIildDQojIyMNCiMjIw0KdGVhY2hlci52bGlkIDwtY2ZhLmFuYWx5c2lzKHRlYWNoZXIwKQ0Kc3R1ZGVudC52bGlkIDwtY2ZhLmFuYWx5c2lzKHN0dWRlbnQwKQ0KIyMNCnZsaWQudGFibGUgPC1yYmluZCh0ZWFjaGVyLmN0cmQgPSB0ZWFjaGVyLnZsaWQsIHN0dWRlbnQuY3RyZCA9IHN0dWRlbnQudmxpZCkNCnJvdy5uYW1lIDwtIGMoInRlYWNoZXIuY3RyZCIsICJzdHVkZW50LmN0cmQiKQ0Kcm93bmFtZXModmxpZC50YWJsZSkgPC0gcm93Lm5hbWUNCmNvbG5hbWVzKHZsaWQudGFibGUpIDwtIGMoInN0ZC5hbGwubWluIiwJInB2YWwubWF4IiwJInNybXIiLAkiY2ZpIiwJInRsaSIpDQpwYW5kZXIodmxpZC50YWJsZSkNCmBgYA0KDQoqKlJlbGlhYmlsaXR5IE1lYXN1cmVzKioNCg0KYGBge3IgZWNobyA9IFRSVUUsIGV2YWwgPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmc9RkFMU0V9DQp0ZWFjaGVyIDwtIFN0cmF0ZWdlLnd0LnBjYVssYygiRGVkdWN0aXZlIiwgIkRlbW9uc3RyYXRpdmUiLCAiTGVjdHVyZSIsICJSZXBldGl0aXZlIildDQpzdHVkZW50IDwtIFN0cmF0ZWdlLnd0LnBjYVssYygiQ29vcGVyYXRpdmUiLCAiSW5kdWN0aXZlIiwgIkludGVncmF0aXZlIildDQojIw0KdGVhY2hlci5yZWxpYWJpbGl0eSA8LSBSZWxpYWJpbGl0eS5mdW4odGVhY2hlcikNCnN0dWRlbnQucmVsaWFiaWxpdHkgPC0gUmVsaWFiaWxpdHkuZnVuKHN0dWRlbnQpDQojIw0KUmVsLnRhYmxlIDwtcmJpbmQodGVhY2ggPSBhbnhpZXR5Lm1lYS5yZWwsIGFueGlldHkubWxhID0gYW54aWV0eS5tbGEucmVsKQ0Kcm93Lm5hbWUgPC0gYygiVGVhY2hlciIsICJTdHVkZW50IikNCmNvbC5uYW1lIDwtIGMoIkNyb25iYWNoIGFscGhhIiwgIk1jRG9uYWxkJ3MgT21lZ2EiKQ0Kcm93bmFtZXMoUmVsLnRhYmxlKSA8LSByb3cubmFtZQ0KY29sbmFtZXMoUmVsLnRhYmxlKSA8LSBjb2wubmFtZQ0KcGFuZGVyKFJlbC50YWJsZSkNCmBgYA0KDQpUaGUgYWJvdmUgZ29vZG5lc3Mtb2YtZml0IGFuZCByZWxpYWJpbGl0eSBtZWFzdXJlcyBleGNlZWQgdGhlIHJlcXVpcmVkIHRocmVzaG9sZHMgb2YgdmFsaWRpdHkgYW5kIHJlbGlhYmlsaXR5IG9mIGFuIGluc3RydW1lbnQuIFRoZSAqKmRvdWJseSB3ZWlnaHRlZCBhdmVyYWdlKiogb2YgdGhlIG9yaWdpbmFsIGNvbXBvc2l0ZSBzY29yZXMgb2YgdGVhY2hpbmcgc3RyYXRlZ2llcyBhbmQgYXBwZW5kZWQgdG8gdGhlIGFuYWx5dGljIGRhdGFzZXQuDQoNCg0KYGBge3J9DQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyANCiMjIyMjIA0Kc2NvcmVzID0gZnVuY3Rpb24oZGYsIGRuKXsNCiAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQogICMjIHNpbmdsZSBmYWN0b3Igc2NvcmUNCiAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiAgeC52YXIgPC0gbmFtZXMoZGYpDQogIG4wIDwtIGxlbmd0aCh4LnZhcikNCiAgY2ZhLm1vZGVsIDwtICBwYXN0ZSgibGF0ZW50ID1+IiwgcGFzdGUoeC52YXIsIGNvbGxhcHNlID0gIiArICIpKQ0KICBjZmEuZml0IDwtIGNmYShjZmEubW9kZWwsIGRhdGEgPSBkZiwgZXN0aW1hdG9yID0gIk1MTSIpDQogIGNvbXBvc2l0ZS5jZmEgPC0gbGF2UHJlZGljdChjZmEuZml0KQ0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KICAjIHBjYSBhbmFseXNpcw0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KICBwY2EubWRsIDwtIHByY29tcChkZiwgc2NhbGUgPSBUUlVFKQ0KICBwY2EwIDwtIHBjYS5tZGwkeFssIDFdDQogIHIwID0gY29yKHBjYTAsIGNvbXBvc2l0ZS5jZmEpDQogIGlmKHIwIDwgMCkgew0KICAgICBwY2EuYWxsIDwtIC1wY2EubWRsJHgNCiAgfWVsc2V7DQogICAgcGNhLmFsbCA8LSBwY2EubWRsJHgNCiAgfQ0KICBmaXJzdC5wY2EgPSBwY2EuYWxsWywxXQ0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KICAjIHdlaWdodGVkIHBjYSBzY29yZQ0KICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KICB2YXIuZXhwbGFpbmVkIDwtKChwY2EubWRsJHNkZXYpXjIpIC8gc3VtKChwY2EubWRsJHNkZXYpXjIpICMNCiAgY29tcG9zaXRlX3dlaWdodGVkX3BjYSA8LSBhcy5tYXRyaXgocGNhLmFsbCkgJSolICh2YXIuZXhwbGFpbmVkKQ0KDQogIG91dGRhdGEgPC0gYXMuZGF0YS5mcmFtZShjYmluZChwY2ExID0gZmlyc3QucGNhLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHd0LnBjYSA9IGFzLnZlY3Rvcihjb21wb3NpdGVfd2VpZ2h0ZWRfcGNhKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICBjZmEgPSBhcy52ZWN0b3IoY29tcG9zaXRlLmNmYSkpKQ0KICBuYW1lcyhvdXRkYXRhKSA8LSBwYXN0ZTAoZG4sIi4iLCBuYW1lcyhvdXRkYXRhKSwgc2VwID0gIiIpDQogIG91dGRhdGENCiB9DQojIyMNCnRlYWNoZXIgPC0gc2NvcmVzKHRlYWNoZXIsICJUZWFjaGVyLmN0cmQiKQ0Kc3R1ZGVudCA8LSBzY29yZXMoc3R1ZGVudCwgIlN0dWRlbnQuY3RyZCIpDQpBbnhpZXR5LkFuYWx5dGljLkRhdGEgPC0gY2JpbmQoZmluYWxEYXQsIHRlYWNoZXIsIHN0dWRlbnQpDQpgYGANCg0KYGBge3IgZWNobyA9IEZBTFNFLCBldmFsID0gRkFMU0V9DQp3cml0ZS5jc3YoQW54aWV0eS5BbmFseXRpYy5EYXRhLCAiQzpcXFVzZXJzXFw3NUNQRU5HXFxPbmVEcml2ZSAtIFdlc3QgQ2hlc3RlciBVbml2ZXJzaXR5IG9mIFBBXFxEZXNrdG9wXFxjcGVuZ1xcV0NVLVRlYWNoaW5nXFwyMDI1RmFsbFxcTWF0aEF4aWV0eVxcQW54aWV0eS5BbmFseXRpYy5EYXRhLmNzdiIpDQpgYGANCg0KDQoNCiMgTGluZWFyIFJlZ3Jlc3Npb24gQW5hbHlzaXMNCg0KVGhpcyBzZWN0aW9uIG1vdmVzIGZyb20gdGhlIHByZXZpb3VzIGRlc2NyaXB0aXZlIGFuYWx5c2VzIHRvIGEgcmVncmVzc2lvbiBhbmFseXNpcyBvZiB0aGUgYXNzb2NpYXRpb24gYmV0d2VlbiBtYXRoIGFueGlldHkgYW5kIHJlbGF0ZWQgZmFjdG9ycy4gV2UgZXhhbWluZSB0d28gZGlzdGluY3QgYnV0IGludGVyY29ubmVjdGVkIHR5cGVzIG9mIG1hdGggYW54aWV0eSwgZXZhbHVhdGlvbiBhbnhpZXR5IGFuZCBsZWFybmluZyBhbnhpZXR5LCB3aGlsZSB0ZW1wb3JhcmlseSBzZXR0aW5nIGFzaWRlIHRoZWlyIGludGVyY29ubmVjdGlvbi4NCg0KVGhlIHJlZ3Jlc3Npb24gbW9kZWwgYWxzbyBpbmNvcnBvcmF0ZXMgdGhlIHR3byB0ZWFjaGluZyBzdHJhdGVnaWVzIGFzIHByZWRpY3RvciB2YXJpYWJsZXMuIFdlIGFsc28gcmVhbGl6ZWQgdGhhdCB0aGUgdHdvIHZhcmlhYmxlcyBhcmUgY29ycmVsYXRlZC4gDQoNCg0KYGBge3IgZWNobyA9IEZBTFNFLCBldmFsID0gVFJVRX0NCmFueGlldHkuaW5mLmRhdGEwIDwtIHJlYWQuY3N2KCJodHRwczovL3Blbmdkc2NpLmdpdGh1Yi5pby9NYXRoQW54aWV0eS9BbnhpZXR5LkFuYWx5dGljLkRhdGEuY3N2IikNCmluZi52YXIgPC0gYygiQW54aWV0eS5tZWEud3QucGNhIiwgIkFueGlldHkubWxhLnd0LnBjYSIsICJzZXgiLCAicmFjZSIsICJjbGFzcyIsICJtYWpvciIsICJtYXRoLmxldmVsIiwgIm1vZGFsaXR5IiwgIlNlbGZFZmZpY2FjeS53dC5wY2EiLCAiVGVjaG5vbG9neS53dC5wY2EiLA0KICJDb29wb3JhdGl2ZS53dC5wY2EiLCAiRGVkdWN0aXZlLnd0LnBjYSIsICJEZW1vbnN0cmF0aW9uLnd0LnBjYSIsICJJbmR1Y3RpdmUud3QucGNhIiwgICAgIkludGVncmF0aXZlLnd0LnBjYSIsICJMZWN0dXJlVHlwZS53dC5wY2EiLCAiUmVwZXRpdGl2ZS53dC5wY2EiLCAiRW5nYWdlLnd0LnBjYSIsICJSZXNvdXJjZS53dC5wY2EiLCJUZWFjaGVyLmN0cmQud3QucGNhIiwgIlN0dWRlbnQuY3RyZC53dC5wY2EiKQ0KIyMNCmFueGlldHkucmVnLmRhdGEgPC0gYW54aWV0eS5pbmYuZGF0YTBbLCBpbmYudmFyXQ0KcmVnLnZhci5uYW1lIDwtIGMoIk1FQSIsICJNTEEiLCAic2V4IiwgInJhY2UiLCAiY2xhc3MiLCAibWFqb3IiLCAibWF0aC5sZXZlbCIsICJtb2RhbGl0eSIsICJTZWxmRWZmaWNhY3kiLCAiVGVjaG5vbG9neSIsDQogIkNvb3BvcmF0aXZlIiwgIkRlZHVjdGl2ZSIsICJEZW1vbnN0cmF0aW9uIiwgIkluZHVjdGl2ZSIsICAgICJJbnRlZ3JhdGl2ZSIsICJMZWN0dXJlIiwgIlJlcGV0aXRpdmUiLCAiRW5nYWdlIiwgIlJlc291cmNlIiwiVGVhY2hlckN0cmQiLCAiU3R1ZGVudEN0cmQiKQ0KbmFtZXMoYW54aWV0eS5yZWcuZGF0YSkgPC0gcmVnLnZhci5uYW1lIA0KYGBgDQoNCg0KIyMgIEZhY3RvcnMgQXNzb2NpYXRlZCB3aXRoIEV2YWx1YXRpb24gQW54aWV0eQ0KDQpGb3IgdGhlIGFzc29jaWF0aW9uIGFuYWx5c2lzLCB3ZSB3aWxsIGJ1aWxkIHR3byByZWdyZXNzaW9uIG1vZGVscy4gQm90aCBtb2RlbHMgaW5jbHVkZSBhIGNvbW1vbiBzZXQgb2YgZGVtb2dyYXBoaWMgcHJlZGljdG9ycy4gVGhlIGZpcnN0IG1vZGVsIHVzZXMgaW5kaXZpZHVhbCB0ZWFjaGluZyBzdHJhdGVnaWVzIGFzIGFkZGl0aW9uYWwgcHJlZGljdG9ycywgd2hpbGUgdGhlIHNlY29uZCB1c2VzIGdyb3VwZWQgdGVhY2hpbmcgc3RyYXRlZ2llcy4NCg0KIyMjIFVzaW5nIEluZGl2aWR1YWwgVGVhY2hpbmcgU3RyYXRlZ2llcw0KDQpUaGUgYW5hbHlzaXMgYmVnaW5zIHdpdGggYSByZWdyZXNzaW9uIG1vZGVsIGluY29ycG9yYXRpbmcgYWxsIGluZGl2aWR1YWwgdGVhY2hpbmcgYXBwcm9hY2hlcyBhbG9uZ3NpZGUgZGVtb2dyYXBoaWMgYW5kIHJlbGF0ZWQgdmFyaWFibGVzIGFzIHByZWRpY3RvcnMuDQoNCmBgYHtyfQ0KQmVzdFN1YnNldHNSZWcgPC0gZnVuY3Rpb24oYmVzdC5zdWJzZXQubW9kZWwpew0KICAgIyBWaWV3IHRoZSByZXN1bHRzDQogICByZWcuc3VtbWFyeSA8LSBzdW1tYXJ5KGJlc3Quc3Vic2V0Lm1vZGVsKQ0KIA0KICAgIyBQbG90dGluZyB0aGUgcmVzdWx0cyAob3B0aW9uYWwsIGZvciB2aXN1YWxpemF0aW9uKQ0KICAgIyBwbG90KGJlc3Quc3Vic2V0Lm1vZGVsLCBzY2FsZSA9ICJhZGpyMiIsIGNvbCA9ICJza3libHVlIikgIyBvciAiYmljIiwgImNwIiwgZXRjLg0KICAgcGFyKG1mcm93ID0gYygyLDIpKQ0KICAgcGxvdChyZWcuc3VtbWFyeSRyc3MsIHhsYWIgPSAiTnVtYmVyIG9mIFZhcmlhYmxlcyIsIHlsYWIgPSAiUlNTIiwgdHlwZSA9ICJsIiwgY29sID0gIm5hdnkiKQ0KICAgcGxvdChyZWcuc3VtbWFyeSRhZGpyMiwgeGxhYiA9ICJOdW1iZXIgb2YgVmFyaWFibGVzIiwgeWxhYiA9ICJBZGp1c3RlZCBSU3EiLCB0eXBlID0gImwiLCBjb2wgPSAibmF2eSIpDQogICAjIFdlIHdpbGwgbm93IHBsb3QgYSByZWQgZG90IHRvIGluZGljYXRlIHRoZSBtb2RlbCB3aXRoIHRoZSBsYXJnZXN0IGFkanVzdGVkIFJeMiBzdGF0aXN0aWMuDQogICAjIFRoZSB3aGljaC5tYXgoKSBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBpZGVudGlmeSB0aGUgbG9jYXRpb24gb2YgdGhlIG1heGltdW0gcG9pbnQgb2YgYSB2ZWN0b3INCiAgIGFkai5yMi5tYXggPSB3aGljaC5tYXgocmVnLnN1bW1hcnkkYWRqcjIpIA0KDQogICAjIFRoZSBwb2ludHMoKSBjb21tYW5kIHdvcmtzIGxpa2UgdGhlIHBsb3QoKSBjb21tYW5kLCBleGNlcHQgdGhhdCBpdCBwdXRzIHBvaW50cyANCiAgICMgb24gYSBwbG90IHRoYXQgaGFzIGFscmVhZHkgYmVlbiBjcmVhdGVkIGluc3RlYWQgb2YgY3JlYXRpbmcgYSBuZXcgcGxvdA0KICAgcG9pbnRzKGFkai5yMi5tYXgsIHJlZy5zdW1tYXJ5JGFkanIyW2Fkai5yMi5tYXhdLCBjb2wgPSJkYXJrcmVkIiwgY2V4ID0gMiwgcGNoID0gMjApDQogICAjIFdlJ2xsIGRvIHRoZSBzYW1lIGZvciBDX3AgYW5kIEJJQywgdGhpcyB0aW1lIGxvb2tpbmcgZm9yIHRoZSBtb2RlbHMgd2l0aCB0aGUgU01BTExFU1Qgc3RhdGlzdGljDQogICBwbG90KHJlZy5zdW1tYXJ5JGNwLCB4bGFiID0gIk51bWJlciBvZiBWYXJpYWJsZXMiLCB5bGFiID0gIkNwIiwgdHlwZSA9ICJsIikNCiAgIGNwLm1pbiA9IHdoaWNoLm1pbihyZWcuc3VtbWFyeSRjcCkgIyAxMA0KICAgcG9pbnRzKGNwLm1pbiwgcmVnLnN1bW1hcnkkY3BbY3AubWluXSwgY29sID0gImRhcmtyZWQiLCBjZXggPSAyLCBwY2ggPSAyMCkNCg0KICAgcGxvdChyZWcuc3VtbWFyeSRiaWMsIHhsYWIgPSAiTnVtYmVyIG9mIFZhcmlhYmxlcyIsIHlsYWIgPSAiQklDIiwgdHlwZSA9ICJsIikNCiAgIGJpYy5taW4gPSB3aGljaC5taW4ocmVnLnN1bW1hcnkkYmljKSAjIDYNCiAgIHBvaW50cyhiaWMubWluLCByZWcuc3VtbWFyeSRiaWNbYmljLm1pbl0sIGNvbCA9ICJkYXJrcmVkIiwgY2V4ID0gMiwgcGNoID0gMjApDQp9DQpgYGANCg0KYGBge3IgZWNobyA9IFRSVUUsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9NX0NCm1lYS5sbS5kYXRhIDwtIGFueGlldHkucmVnLmRhdGFbLC1jKDIsMjAsMjEpXQ0KbWVhLmJlc3Quc3Vic2V0cy5sbSA8LSByZWdzdWJzZXRzKE1FQSB+LiwgZGF0YSA9IG1lYS5sbS5kYXRhLCBudm1heCA9IDgsICBtZXRob2QgPSAiYmFja3dhcmQiICkNCkJlc3RTdWJzZXRzUmVnKG1lYS5iZXN0LnN1YnNldHMubG0pDQpgYGANCg0KVGhlIGFib3ZlIGZpZ3VyZSBpbmRpY2F0ZXMgdGhhdCB0aGUgNi1wcmVkaWN0b3IgbW9kZWwgaXMgdGhlIG9wdGltYWwgY2hvaWNlLiBUaGUgcmVzdWx0cyBvYnRhaW5lZCBmcm9tIHRoaXMgc3Vic2V0IHNlbGVjdGlvbiBtZXRob2QgYXJlIGlkZW50aWNhbCB0byB0aG9zZSBvYnRhaW5lZCB2aWEgc3RlcHdpc2UgdmFyaWFibGUgc2VsZWN0aW9uLg0KDQpgYGB7ciBlY2hvID0gVFJVRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD03fQ0KbWVhLmxtLmRhdGEgPC0gYW54aWV0eS5yZWcuZGF0YVssLWMoMiwyMCwyMSldDQptZWEubG0gPC0gbG0oTUVBIH5TZWxmRWZmaWNhY3kgKyBJbmR1Y3RpdmUgKyBJbnRlZ3JhdGl2ZSArIG1hdGgubGV2ZWwgKyBzZXggKw0KICAgIFRlY2hub2xvZ3ksIGRhdGEgPSBtZWEubG0uZGF0YSkNCnN0ZXB3aXNlLm1lYS5tb2RlbCA8LSBzdGVwQUlDKG1lYS5sbSwgZGlyZWN0aW9uID0gImJvdGgiLCB0cmFjZSA9IDApDQojc3VtbWFyeShzdGVwd2lzZS5tZWEubW9kZWwpDQpwYXIobWZyb3cgPSBjKDIsMikpDQpwbG90KHN0ZXB3aXNlLm1lYS5tb2RlbCApDQpgYGANCg0KVGhlIGZpZ3VyZSBhYm92ZSByZXZlYWxzIGEgY2xlYXIgcGF0dGVybiBvZiBub24tY29uc3RhbnQgcmVzaWR1YWwgdmFyaWFuY2UgKGhldGVyb3NjZWRhc3RpY2l0eSkgYXMgdGhlIGZpdHRlZCB2YWx1ZXMgaW5jcmVhc2UuIEJlY2F1c2UgdGhlIHJlc3BvbnNlIHZhcmlhYmxlIGluY2x1ZGVzIG5lZ2F0aXZlIHZhbHVlcywgYSBzdGFuZGFyZCBCb3gtQ294IHRyYW5zZm9ybWF0aW9uIGlzIG5vdCBhcHBsaWNhYmxlIGZvciBpZGVudGlmeWluZyBhIHBvd2VyIHRyYW5zZm9ybWF0aW9uLiBJbnN0ZWFkLCB3ZSB3aWxsIHVzZSBib290c3RyYXAgY29uZmlkZW5jZSBpbnRlcnZhbHMgZm9yIGFsbCByZWdyZXNzaW9uIGNvZWZmaWNpZW50cyB0byBhc3Nlc3MgdGhlaXIgc2lnbmlmaWNhbmNlLCB0aGVyZWJ5IG1haW50YWluaW5nIHRoZSByZXNwb25zZSB2YXJpYWJsZSBvbiBpdHMgb3JpZ2luYWwgc2NhbGUuDQoNCg0KYGBge3J9DQojIyMgQm9vdHN0cmFwIGNvbmZpZGVuY2UgaW50ZXJ2YWxzDQpib290LmNvZWYgPC0gZnVuY3Rpb24oZGF0YSwgaW5kaWNlcykgew0KICBkIDwtIGRhdGFbaW5kaWNlcywgXSAgIyByZXNhbXBsZSByb3dzDQogIGZpdCA8LSBsbShNRUEgfiBTZWxmRWZmaWNhY3kgKyBJbnRlZ3JhdGl2ZSArIG1hdGgubGV2ZWwgKyANCiAgICBzZXggKyBUZWNobm9sb2d5LCBkYXRhID0gZCkNCiAgcmV0dXJuKGNvZWYoZml0KSkgICAgICAjIHJldHVybiBjb2VmZmljaWVudHMNCn0NCiMjIyMjIw0KIyBFeHRyYWN0IENJcyBmb3IgYWxsIGNvZWZmaWNpZW50cw0KZ2V0LmFsbC5ib290LmNpcyA8LSBmdW5jdGlvbihib290Lm91dHB1dCwgdHlwZSA9ICJwZXJjIikgew0KICBuLmNvZWYgPC0gbmNvbChib290Lm91dHB1dCR0KQ0KICBjaS5tYXRyaXggPC0gbWF0cml4KE5BLCBucm93ID0gbi5jb2VmLCBuY29sID0gMikNCiAgcm93bmFtZXMoY2kubWF0cml4KSA8LSBjb2xuYW1lcyhib290Lm91dHB1dCR0KQ0KICBjb2xuYW1lcyhjaS5tYXRyaXgpIDwtIGMoImJ0Lmxvdy45NSUiLCAiYnQudXAuOTUlIikNCiAgDQogIGZvciAoaSBpbiAxOm4uY29lZikgew0KICAgIGNpLm9iaiA8LSBib290LmNpKGJvb3Qub3V0cHV0LCB0eXBlID0gdHlwZSwgaW5kZXggPSBpKQ0KICAgIGlmICh0eXBlID09ICJwZXJjIikgew0KICAgICAgY2kubWF0cml4W2ksIF0gPC0gY2kub2JqJHBlcmNlbnRbNDo1XQ0KICAgIH0NCiAgfQ0KICANCiAgcmV0dXJuKGNpLm1hdHJpeCkNCn0NCg0KYGBgDQoNCmBgYHtyfQ0KIyBQZXJmb3JtIGJvb3RzdHJhcCAoUiA9IG51bWJlciBvZiByZXNhbXBsZXMpDQpzZXQuc2VlZCgzMTEpICAjIGZvciByZXByb2R1Y2liaWxpdHkNCmJvb3QucmVzdWx0cyA8LSBib290KG1lYS5sbS5kYXRhLCBib290LmNvZWYsIFIgPSAxMDAwKQ0KYGBgDQoNCmBgYHtyfQ0KYWxsLmNpcyA8LSBnZXQuYWxsLmJvb3QuY2lzKGJvb3QucmVzdWx0cykNCkluZmVyZW5jZVRhYmxlIDwtIHJvdW5kKGNiaW5kKHN1bW1hcnkoc3RlcHdpc2UubWVhLm1vZGVsKSRjb2VmLCBhbGwuY2lzKSw0KQ0KcHJpbnQoSW5mZXJlbmNlVGFibGUpIA0KYGBgDQoNCg0KDQpUaGUgYWJvdmUgdGFibGUgcmV2ZWFsZWQgc2V2ZXJhbCBzaWduaWZpY2FudCBwcmVkaWN0b3JzIG9mIG1hdGggZXZhbHVhdGlvbiBhbnhpZXR5LiBIaWdoZXIgKipzZWxmLWVmZmljYWN5Kiogd2FzIHN0cm9uZ2x5IGFzc29jaWF0ZWQgd2l0aCBsb3dlciBhbnhpZXR5ICgkXGJldGEgPSAtMC41NzcsIHAgPCAwLjAwMSQpLCBpbmRpY2F0aW5nIHRoYXQgc3R1ZGVudHMgd2hvIGFyZSBtb3JlIGNvbmZpZGVudCBpbiB0aGVpciBtYXRoZW1hdGljYWwgYWJpbGl0aWVzIGV4cGVyaWVuY2UgbGVzcyAqKmV2YWx1YXRpb24tcmVsYXRlZCBzdHJlc3MqKi4gU2ltaWxhcmx5LCAqKmludGVncmF0aXZlIGluc3RydWN0aW9uIGFwcHJvYWNoKiogc2hvd2VkIGEgbmVnYXRpdmUgcmVsYXRpb25zaGlwIHdpdGggYW54aWV0eSAoJFxiZXRhID0gLTAuMTc4LCBwIDwgMC4wMDEkKSwgIGltcGx5aW5nIHRoYXQgdGhpcyB0ZWFjaGluZyBtZXRob2QgbWF5IGhlbHAgcmVkdWNlIHN0dWRlbnQgYW54aWV0eS4gKipDb3Vyc2UgbGV2ZWwqKiBhbHNvIHBsYXllZCBhIHJvbGU6IHN0dWRlbnRzIGVucm9sbGVkIGluIG1hdGgwMyAoY2FsYyBBIGFuZCBicmllZiBDYWxjKSAoJFxiZXRhID0gMC4yNzYsIHAgPSAwLjA0MCQpIGFuZCBtYXRoMDQgKGFib3ZlIENhbGMgQSkgKCRcYmV0YSA9IDAuMzYzLCBwID0gMC4wMjMkKSBjb3Vyc2VzIGV4aGliaXRlZCBoaWdoZXIgYW54aWV0eSBjb21wYXJlZCB0byB0aGUgcmVmZXJlbmNlIGdyb3VwLCB3aGlsZSBvdGhlciBjb3Vyc2UgbGV2ZWxzIHdlcmUgbm90IHNpZ25pZmljYW50LiAqKkdlbmRlcioqIHdhcyBhIHNpZ25pZmljYW50IGZhY3Rvciwgd2l0aCBtYWxlIHN0dWRlbnRzIHJlcG9ydGluZyBsb3dlciBhbnhpZXR5IHRoYW4gZmVtYWxlcyAoJFxiZXRhID0gLTAuMzQ0LCBwIDwgMC4wMDEkKS4gRmluYWxseSwgKip0ZWNobm9sb2d5IHVzZSoqIHdhcyBuZWdhdGl2ZWx5IGFzc29jaWF0ZWQgd2l0aCBhbnhpZXR5ICgkXGJldGEgPSAtMC4xMzcsIHAgPCAwLjAwMSQpLCBpbmRpY2F0aW5nIHRoYXQgZ3JlYXRlciBlbmdhZ2VtZW50IHdpdGggdGVjaG5vbG9neSBjb3JyZXNwb25kcyB0byByZWR1Y2VkIG1hdGggZXZhbHVhdGlvbiBhbnhpZXR5LiANCg0KSW4gc3VtbWFyeSwgbWF0aCBldmFsdWF0aW9uIGFueGlldHkgd2FzIHNpZ25pZmljYW50bHkgbG93ZXIgYW1vbmcgc3R1ZGVudHMgd2l0aCBoaWdoZXIgKipzZWxmLWVmZmljYWN5KiouICBBbiAqKmludGVncmF0aXZlIHRlYWNoaW5nIGFwcHJvYWNoKiogYW5kIGFwcHJvcHJpYXRlICoqdXNlIG9mIHRlY2hub2xvZ3kqKiBtYXkgaGVscCByZWR1Y2UgbWF0aCBldmFsdWF0aW9uIGFueGlldHkuIE1hbGUgc3R1ZGVudHMgdGVuZGVkIHRvIGV4cGVyaWVuY2UgbGVzcyBzdHJlc3MuIENvbnZlcnNlbHksIHN0dWRlbnRzIGVucm9sbGVkIGluIGhpZ2hlci1sZXZlbCBtYXRoIGNvdXJzZXMgKG1hdGgwMyBhbmQgbWF0aDA0KSByZXBvcnRlZCBzbGlnaHRseSBoaWdoZXIgYW54aWV0eS4gDQoNCg0KIyMjIFVzaW5nIEdyb3VwZWQgVGVhY2hpbmcgU3RyYXRlZ2llcw0KDQpOZXh0LCB3ZSBidWlsZCBhIHJlZ3Jlc3Npb24gbW9kZWwgdXNpbmcgdGhlIGFnZ3JlZ2F0ZWQgdGVhY2hpbmcgc3R5bGVzOiB0ZWFjaGVyLWNlbnRlcmVkIGFuZCBzdHVkZW50LWNlbnRlcmVkLCBwbHVzIHNvbWUgZGVtb2dyYXBoaWMgZmFjdG9ycy4NCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD02fQ0KIyBQZXJmb3JtIGJlc3Qgc3Vic2V0IHNlbGVjdGlvbg0KIyAnbnZtYXgnIHNwZWNpZmllcyB0aGUgbWF4aW11bSBudW1iZXIgb2YgdmFyaWFibGVzIHRvIGNvbnNpZGVyIGluIGEgc3Vic2V0DQpiZXN0LnN1YnNldC5tb2RlbC5jdHJkIDwtIHJlZ3N1YnNldHMoTUVBfiBzZXgrIHJhY2UrIGNsYXNzKyBtYWpvcisgbWF0aC5sZXZlbCsgbW9kYWxpdHkrIFNlbGZFZmZpY2FjeSsgVGVjaG5vbG9neSArIFRlYWNoZXJDdHJkKyBTdHVkZW50Q3RyZCwgZGF0YSA9IGFueGlldHkucmVnLmRhdGEsIG52bWF4ID0gMTAsICBtZXRob2QgPSAiYmFja3dhcmQiICkNCkJlc3RTdWJzZXRzUmVnKGJlc3Quc3Vic2V0Lm1vZGVsLmN0cmQpDQpgYGANCg0KYGBge3J9DQpjb2VmKGJlc3Quc3Vic2V0Lm1vZGVsLmN0cmQsNikNCmBgYA0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD02fQ0KIyBUaGUgZmluYWwgbW9kZWwNCmJlc3Quc3Vic2V0LmN0cmQgPC0gbG0oTUVBfiBzZXgrIG1hdGgubGV2ZWwrICBTZWxmRWZmaWNhY3krIFRlY2hub2xvZ3kgKyBTdHVkZW50Q3RyZCwgZGF0YSA9IGFueGlldHkucmVnLmRhdGEpDQojc3VtbWFyeShiZXN0LnN1YnNldC5jdHJkKSRjb2VmDQpwYXIobWZyb3cgPSBjKDIsMikpDQpwbG90KGJlc3Quc3Vic2V0LmN0cmQpDQpgYGANCg0KV2UgbmV4dCBwZXJmb3JtIEJvb3RzdHJhcCByZWdyZXNzaW9uIHRvIGNvbnN0cnVjdCByb2J1c3QgY29uZmlkZW5jZSBpbnRlcnZhbHMgZm9yIHRoZSByZWdyZXNzaW9uIGNvZWZmaWNpZW50cy4NCg0KYGBge3J9DQojIyMgQm9vdHN0cmFwIGNvbmZpZGVuY2UgaW50ZXJ2YWxzDQpib290LmNvZWYuY3RyZCA8LSBmdW5jdGlvbihkYXRhLCBpbmRpY2VzKSB7DQogIGQgPC0gZGF0YVtpbmRpY2VzLCBdICAjIHJlc2FtcGxlIHJvd3MNCiAgZml0IDwtIGxtKE1FQX4gc2V4KyBtYXRoLmxldmVsKyAgU2VsZkVmZmljYWN5KyBUZWNobm9sb2d5ICsgU3R1ZGVudEN0cmQsIGRhdGEgPSBkKQ0KICByZXR1cm4oY29lZihmaXQpKSAgICAgICMgcmV0dXJuIGNvZWZmaWNpZW50cw0KfQ0KYGBgDQoNCg0KYGBge3J9DQojIFBlcmZvcm0gYm9vdHN0cmFwIChSID0gbnVtYmVyIG9mIHJlc2FtcGxlcykNCnNldC5zZWVkKDMxMikgICMgZm9yIHJlcHJvZHVjaWJpbGl0eQ0KYm9vdC5yZXN1bHRzLmN0cmQgPC0gYm9vdChhbnhpZXR5LnJlZy5kYXRhLCBib290LmNvZWYuY3RyZCwgUiA9IDEwMDApDQpgYGANCg0KYGBge3J9DQphbGwuY3RyZC5jaXMgPC0gZ2V0LmFsbC5ib290LmNpcyhib290LnJlc3VsdHMuY3RyZCApDQpJbmZlcmVuY2VUYWJsZSA8LSByb3VuZChjYmluZChzdW1tYXJ5KGJlc3Quc3Vic2V0LmN0cmQpJGNvZWYsIGFsbC5jdHJkLmNpcyApLDQpDQpwcmludChJbmZlcmVuY2VUYWJsZSkgDQpgYGANCg0KVGhlIHJlc3VsdHMgYWJvdmUgYXJlIGNvbnNpc3RlbnQgd2l0aCB0aGUgcHJldmlvdXMgcmVncmVzc2lvbiB0aGF0IHVzZWQgaW5kaXZpZHVhbCB0ZWFjaGluZyBzdHJhdGVnaWVzIGFzIHByZWRpY3RvcnMuIFRoZSBrZXkgZGlmZmVyZW5jZSBpcyB0aGF0IHRoZSAqKmludGVncmF0aXZlIHRlYWNoaW5nIGFwcHJvYWNoKiogd2FzIHNpZ25pZmljYW50IGluIHRoZSBmb3JtZXIgbW9kZWwsIHdoZXJlYXMgKipzdHVkZW50LWNlbnRlcmVkKiogdGVhY2hpbmcgc3RyYXRlZ2llcyBhcmUgc2lnbmlmaWNhbnQgaW4gdGhlIGN1cnJlbnQgb25lLiBIb3dldmVyLCBzaW5jZSBhbiBpbnRlZ3JhdGl2ZSBhcHByb2FjaCBpcyBhIHNwZWNpZmljIHR5cGUgb2Ygc3R1ZGVudC1jZW50ZXJlZCBzdHJhdGVneSwgdGhlIG1vZGVscyB1bHRpbWF0ZWx5IHlpZWxkIGNvbmdydWVudCBmaW5kaW5ncy4NCg0KDQoNCiMjIEZhY3RvcnMgQXNzb2NpYXRlZCB3aXRoIExlYXJuaW5nIEFueGlldHkNCg0KVW5saWtlIG1hdGggZXZhbHVhdGlvbiBhbnhpZXR5LCB3aGljaCBpcyBmdWVsZWQgbW9yZSBieSBlbW90aW9uYWwgYW5kIGVudmlyb25tZW50YWwgZmFjdG9ycywgbWF0aCBsZWFybmluZyBhbnhpZXR5IGlzIGEgZGlyZWN0IHJlc3BvbnNlIHRvIHRoZSBsZWFybmluZyBlY29zeXN0ZW0uIEl0IGlzIGNsb3NlbHkgbGlua2VkIHRvIHRoZSBkZW5zaXR5IG9mIHRoZSBsZWFybmluZyBtYXRlcmlhbHMsIHRoZSBzaWduaWZpY2FudCBjb2duaXRpdmUgbG9hZCByZXF1aXJlZCBmb3IgcHJvYmxlbS1zb2x2aW5nLCBhbmQgY3JpdGljYWwgZXh0ZXJuYWwgZmFjdG9ycyBzdWNoIGFzIGluc3RydWN0b3JzJyB0ZWFjaGluZyBzdHJhdGVnaWVzLiANCg0KVGhlIG5leHQgcmVncmVzc2lvbiBtb2RlbCBhaW1zIHRvIGlkZW50aWZ5IGZhY3RvcnMgdGhhdCBhcmUgZGlyZWN0bHkgYXNzb2NpYXRlZCB3aXRoIHRoZSBtYXRoIGxlYXJuaW5nIGFueGlldHkuIFdlIHN0aWxsIHRha2UgdGhlIGJlc3Qgc3Vic2V0IHNlbGVjdGlvbiBhcHByb2FjaCB0byBpZGVudGlmeWluZyB0aGUgYmVzdCBtb2RlbC4NCg0KDQojIyMgVXNpbmcgSW5kaXZpZHVhbCBUZWFjaGluZyBTdHJhdGVnaWVzDQoNClRoZSBmb2xsb3dpbmcgbW9kZWwgdXNlcyBpbmRpdmlkdWFsIHRlYWNoaW5nIHN0cmF0ZWdpZXMgYXMgcHJlZGljdG9ycy4gVGhpcyB3aWxsIGhlbHAgaWRlbnRpZnkgcGFydGljdWxhciB0ZWFjaGluZyBzdHJhdGVnaWVzIHRoYXQgYXJlIHNpZ25pZmljYW50bHkgYXNzb2NpYXRlZCB3aXRoIHRoZSBsZWFuaW5nIGFueGlldHkuDQoNCg0KYGBge3IgZWNobyA9IFRSVUUsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9Nn0NCm1sYS5sbS5kYXRhIDwtIGFueGlldHkucmVnLmRhdGFbLC1jKDEsMjAsMjEpXQ0KbWxhLmZ1bGwubG0gPC0gbG0oTUxBIH4uLCBkYXRhID0gbWxhLmxtLmRhdGEpDQpwYXIobWZyb3cgPSBjKDIsMikpDQpwbG90KG1sYS5mdWxsLmxtKQ0KI3N1bW1hcnkobWxhLmZ1bGwubG0pDQpgYGANCg0KDQpUaGlzIGluaXRpYWwgbW9kZWwncyByZXNpZHVhbCBkaWFnbm9zdGljIHBsb3Qgc2hvd3Mgbm9uLWNvbnN0YW50IHZhcmlhbmNlLiBXZSB3aWxsIG5vdCBwZXJmb3JtIGFueSBwb3dlciB0cmFuc2Zvcm1hdGlvbnMgb24gdGhlIHJlc3BvbnNlIHZhcmlhYmxlIGZvciB0aGUgc2FtZSByZWFzb25zIHN0YXRlZCBpbiB0aGUgcHJldmlvdXMgc3Vic2VjdGlvbi4gVGhlIGluZmVyZW5jZSBvbiB0aGUgcmVncmVzc2lvbiBjb2VmZmljaWVudHMgd2lsbCBiYXNlZCBvbiBub25wYXJhbWV0cmljIEJvb3RzdHJhcCBhbmQgdGhlIGNsYXNzaWNhbCB0LXRlc3RzLg0KDQpXZSBuZXh0IHVzZSBiZXN0IHN1YnNldCBtb2RlbCBzZWxlY3Rpb24gYXBwcm9hY2ggdG8gaWRlbnRpZnkgdGhlIG9wdGltYWwgbW9kZWwgdXNpbmcgdmFyaW91cyBwZXJmb3JtYW5jZSBtZWFzdXJlcyBzdWNoIGFzIENwLCBCSUMsIEFkanVzdGVkIGNvZWZmaWNpZW50IG9mIGRldGVybWluYXRpb24gYW5kIHRoZSBsaXN0IG9mIHRoZSBzaWduaWZpY2FudCBwcmVkaWN0b3JzIGluIHRoZSBpbml0aWFsIG1vZGVsIHdpdGggbW9zdCBvZiB0aGUgY2FuZGlkYXRlIHByZWRpY3RvciB2YXJpYWJsZXMuIA0KDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTV9DQptbGEuYmVzdC5zdWJzZXRzLmxtIDwtIHJlZ3N1YnNldHMoTUxBIH4uLCBkYXRhID0gbWxhLmxtLmRhdGEsIG52bWF4ID0gMTYsICBtZXRob2QgPSAiYmFja3dhcmQiICkNCkJlc3RTdWJzZXRzUmVnKG1sYS5iZXN0LnN1YnNldHMubG0pDQpgYGANCg0KYGBge3J9DQpwcmVkLnZhciA8LSBuYW1lcyhjb2VmKG1sYS5iZXN0LnN1YnNldHMubG0gLDcpKVstKDE6MildDQphY3V0YWwudmFyIDwtYygicmFjZSIsIHByZWQudmFyKQ0KZm9ybXVsYS5zdHIgPC0gcGFzdGUoIk1MQSIsICJ+IiwgcGFzdGUoYWN1dGFsLnZhciwgY29sbGFwc2UgPSAiICsgIikpDQpNTEEubW9kZWwuZm9ybXVsYSA8LSBhcy5mb3JtdWxhKGZvcm11bGEuc3RyKQ0KTUxBLm1vZGVsIDwtIGxtKE1MQS5tb2RlbC5mb3JtdWxhICwgZGF0YSA9IG1sYS5sbS5kYXRhKQ0Kc3VtbWFyeShNTEEubW9kZWwgKQ0KYGBgDQoNCmBgYHtyfQ0KIyMjIEJvb3RzdHJhcCBjb25maWRlbmNlIGludGVydmFscw0KYm9vdC5jb2VmLm1sYSA8LSBmdW5jdGlvbihkYXRhLCBpbmRpY2VzKSB7DQogIGQgPC0gZGF0YVtpbmRpY2VzLCBdICAjIHJlc2FtcGxlIHJvd3MNCiAgZml0IDwtIGxtKE1MQS5tb2RlbC5mb3JtdWxhLCBkYXRhID0gZCkNCiAgcmV0dXJuKGNvZWYoZml0KSkgICAgICAjIHJldHVybiBjb2VmZmljaWVudHMNCn0NCmBgYA0KDQpgYGB7cn0NCiMgUGVyZm9ybSBib290c3RyYXAgKFIgPSBudW1iZXIgb2YgcmVzYW1wbGVzKQ0Kc2V0LnNlZWQoMzEyKSAgIyBmb3IgcmVwcm9kdWNpYmlsaXR5DQpib290LnJlc3VsdHMubWxhPC0gYm9vdChtbGEubG0uZGF0YSwgYm9vdC5jb2VmLm1sYSwgUiA9IDEwMDApDQpgYGANCg0KDQpgYGB7cn0NCmFsbC5jaXMubWxhIDwtIGdldC5hbGwuYm9vdC5jaXMoYm9vdC5yZXN1bHRzLm1sYSkNCkluZmVyZW5jZVRhYmxlIDwtIHJvdW5kKGNiaW5kKHN1bW1hcnkoTUxBLm1vZGVsKSRjb2VmLCBhbGwuY2lzLm1sYSksNCkNCnByaW50KEluZmVyZW5jZVRhYmxlKSANCmBgYA0KDQpUaGUgYWJvdmUgcmVzdWx0cyBpbmRpY2F0ZSB0aGF0ICoqU2VsZi1FZmZpY2FjeSoqLCAqKlRlY2hub2xvZ3kgdXNlKiosICoqRGVtb25zdHJhdGlvbioqLCBhbmQgKipMZWN0dXJlLWJhc2VkKiogdGVhY2hpbmcgc3RyYXRlZ2llcyBhcmUgc2lnbmlmaWNhbnQgbmVnYXRpdmUgcHJlZGljdG9ycyBvZiBhbnhpZXR5LiBTcGVjaWZpY2FsbHksIGhpZ2hlciBzZWxmLWVmZmljYWN5ICgkXGJldGEgPSAtMC40MCwgcCA8IC4wMDEkKSBhbmQgZ3JlYXRlciB1c2Ugb2YgKip0ZWNobm9sb2d5KiogaW4gbGVhcm5pbmcgKCRcYmV0YSA9IC0wLjExLCBwIDwgLjAwMSQpIGFyZSBhc3NvY2lhdGVkIHdpdGggbG93ZXIgbGV2ZWxzIG9mIG1hdGggbGVhcm5pbmcgYW54aWV0eS4gU2ltaWxhcmx5LCBtb3JlIGZyZXF1ZW50IHVzZSBvZiAqKmRlbW9uc3RyYXRpdmUqKiAoJFxiZXRhID0gLTAuMTAsIHAgPSAuMDA2JCkgYW5kICoqbGVjdHVyZSBhcHByb2FjaGVzKiogKCRcYmV0YSA9IC0wLjE0LCBwIDwgLjAwMSQpIGNvcnJlc3BvbmQgd2l0aCBkZWNyZWFzZWQgYW54aWV0eS4NCg0KQ29udmVyc2VseSwgdGhlIHBlcmNlaXZlZCAqKkNvb3BlcmF0aXZlKiogdGVhY2hpbmcgYXBwcm9hY2ggaXMgcG9zaXRpdmVseSBhc3NvY2lhdGVkIHdpdGggbGVhcm5pbmcgYW54aWV0eSAoJFxiZXRhID0gMC4wNywgcCA9IC4wMzEkKS4gICoqUmVzb3VyY2UtYmFzZWQqKiBsZWFybmluZyAoJFxiZXRhID0gMC4wOCwgcCA9IC4wMTMkKSBpcyBhbHNvIHBvc2l0aXZlbHkgYXNzb2NpYXRlZCB3aXRoIGFueGlldHksIHN1Z2dlc3RpbmcgdGhhdCBzdHVkZW50IHVzZWQgbGVhcm5pbmcgcmVzb3VyY2VzIHRlbmRlZCB0byBoYXZlIGhpZ2hlciBhbnhpZXR5IGluIG1hdGggY29udGV4dHMuDQoNClRoZSByYWNlIHZhcmlhYmxlIGFwcHJvYWNoZWQgbWFyZ2luYWwgc2lnbmlmaWNhbmNlIChwID0wLjA1OCksIGluZGljYXRpbmcgdGhhdCBCbGFjayBzdHVkZW50cyB0ZW5kZWQgdG8gaGF2ZSBoaWdoZXIgbGVhcm5pbmcgYW54aWV0eSAoJFxiZXRhID0gMC4zMjAyLCBwID0gLjA1OCQpLg0KDQpPdmVyYWxsLCB0aGVzZSByZXN1bHRzIGhpZ2hsaWdodCB0aGF0IHN0dWRlbnRz4oCZIGNvbmZpZGVuY2UgaW4gdGhlaXIgbWF0aCBhYmlsaXRpZXMgYW5kIGNlcnRhaW4gaW5zdHJ1Y3Rpb25hbCBwcmFjdGljZXMgcGxheSBhIGtleSByb2xlIGluIHJlZHVjaW5nIG1hdGggbGVhcm5pbmcgYW54aWV0eSwgd2hpbGUgb3RoZXJzIG1heSBpbmFkdmVydGVudGx5IGluY3JlYXNlIGl0Lg0KDQoNCiMjIyBVc2luZyBHcm91cGVkIFRlYWNoaW5nIFN0cmF0ZWdpZXMNCg0KV2UgbmV4dCBidWlsZCBhIHJlZ3Jlc3Npb24gc2ltaWxhciB0byB0aGUgYWJvdmUgb25lIGJ1dCByZXBsYWNlIHRoZSBpbmRpdmlkdWFsIHRlYWNoaW5nIHN0cmF0ZWd5IHZhcmlhYmxlcyB3aXRoIHRoZSB0d28gZ3JvdXBlZCB0ZWFjaGluZyBzdHJhdGVneSB2YXJpYWJsZXM6IHRlYWNoZXItY2VudGVyZWQgYW1kIHN0dWRlbnQtY2VudGVyZWQgYXBwcm9hY2hlcy4NCg0KDQpgYGB7ciBlY2hvID0gVFJVRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD02fQ0KbWxhLmxtLmRhdGEuY3RyZCA8LSBhbnhpZXR5LnJlZy5kYXRhWywtYygxLCAxMToxNyldDQptbGEuZnVsbC5jdHJkIDwtIGxtKE1MQSB+LiwgZGF0YSA9IG1sYS5sbS5kYXRhLmN0cmQpDQpwYXIobWZyb3cgPSBjKDIsMikpDQpwbG90KG1sYS5mdWxsLmN0cmQpDQojIHN1bW1hcnkobWxhLmZ1bGwuY3RyZCkNCmBgYA0KDQoNCmBgYHtyIGVjaG8gPSBUUlVFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTV9DQptbGEuYmVzdC5zdWJzZXRzLmN0cmQgPC0gcmVnc3Vic2V0cyhNTEEgfi4sIGRhdGEgPSBtbGEubG0uZGF0YS5jdHJkLCBudm1heCA9IDE2LCAgbWV0aG9kID0gImJhY2t3YXJkIiApDQpCZXN0U3Vic2V0c1JlZyhtbGEuYmVzdC5zdWJzZXRzLmN0cmQpDQpgYGANCg0KDQpgYGB7cn0NCnByZWQudmFyLmN0cmQgPC0gbmFtZXMoY29lZihtbGEuYmVzdC5zdWJzZXRzLmN0cmQsNykpWy0oMTozKV0NCmFjdXRhbC52YXIuY3RyZCA8LWMoInJhY2UiLCAibWFqb3IiLCBwcmVkLnZhci5jdHJkKQ0KZm9ybXVsYS5zdHIuY3RyZCA8LSBwYXN0ZSgiTUxBIiwgIn4iLCBwYXN0ZShhY3V0YWwudmFyLmN0cmQsIGNvbGxhcHNlID0gIiArICIpKQ0KTUxBLm1vZGVsLmZvcm11bGEgPC0gYXMuZm9ybXVsYShmb3JtdWxhLnN0ci5jdHJkKQ0KTUxBLm1vZGVsLmN0cmQgPC0gbG0oTUxBLm1vZGVsLmZvcm11bGEgLCBkYXRhID0gbWxhLmxtLmRhdGEuY3RyZCkNCnN1bW1hcnkoTUxBLm1vZGVsLmN0cmQpJGNvZWYNCmBgYA0KDQoNCg0KDQpgYGB7cn0NCiMjIyBCb290c3RyYXAgY29uZmlkZW5jZSBpbnRlcnZhbHMNCmJvb3QuY29lZi5tbGEuY3RyZCA8LSBmdW5jdGlvbihkYXRhLCBpbmRpY2VzKSB7DQogIGQgPC0gZGF0YVtpbmRpY2VzLCBdICAjIHJlc2FtcGxlIHJvd3MNCiAgZml0IDwtIGxtKE1MQS5tb2RlbC5mb3JtdWxhICwgZGF0YSA9IGQpDQogIHJldHVybihjb2VmKGZpdCkpICAgICAgIyByZXR1cm4gY29lZmZpY2llbnRzDQp9DQpgYGANCg0KDQpgYGB7cn0NCiMgUGVyZm9ybSBib290c3RyYXAgKFIgPSBudW1iZXIgb2YgcmVzYW1wbGVzKQ0Kc2V0LnNlZWQoMzEyKSAgIyBmb3IgcmVwcm9kdWNpYmlsaXR5DQpib290LnJlc3VsdHMuY3RyZCA8LSBib290KG1sYS5sbS5kYXRhLmN0cmQsIGJvb3QuY29lZi5tbGEuY3RyZCwgUiA9IDEwMDApDQpgYGANCg0KYGBge3J9DQphbGwuY3RyZC5jaXMgPC0gZ2V0LmFsbC5ib290LmNpcyhib290LnJlc3VsdHMuY3RyZCApDQpJbmZlcmVuY2VUYWJsZSA8LSByb3VuZChjYmluZChzdW1tYXJ5KE1MQS5tb2RlbC5jdHJkKSRjb2VmLCBhbGwuY3RyZC5jaXMgKSw0KQ0KcHJpbnQoSW5mZXJlbmNlVGFibGUpIA0KYGBgDQoNCg0KVGhlIG92ZXJhbGwgbW9kZWwgd2FzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQsIGluZGljYXRpbmcgdGhhdCB0aGUgc2V0IG9mIHByZWRpY3RvcnMgbWVhbmluZ2Z1bGx5IGV4cGxhaW5lZCB2YXJpYW5jZSBpbiBtYXRoIGxlYXJuaW5nIGFueGlldHkuDQoNCkFtb25nIGRlbW9ncmFwaGljIHZhcmlhYmxlcywgKipyYWNlKiogd2FzIGEgc2lnbmlmaWNhbnQgcHJlZGljdG9yLiBTcGVjaWZpY2FsbHksIEJsYWNrIHN0dWRlbnRzIHJlcG9ydGVkIHNpZ25pZmljYW50bHkgaGlnaGVyIGFueGlldHkgdGhhbiB0aGUgcmVmZXJlbmNlIEFzaWFuIGdyb3VwICgkXGJldGEgPSAwLjM0LCBwID0gLjA0MyQpLCB3aGVyZWFzIHN0dWRlbnRzIGlkZW50aWZ5aW5nIGFzIFdoaXRlIG9yIE90aGVyIHJhY2lhbCBncm91cHMgZGlkIG5vdCBkaWZmZXIgc2lnbmlmaWNhbnRseSBmcm9tIHRoZSByZWZlcmVuY2UgZ3JvdXAgKCRwID4gLjA1JCkuIEFkZGl0aW9uYWxseSwgc3R1ZGVudHMgbWFqb3JpbmcgaW4gKipTVEVNKiogZmllbGRzIHJlcG9ydGVkIHNpZ25pZmljYW50bHkgbG93ZXIgYW54aWV0eSBjb21wYXJlZCB0byB0aG9zZSBvdXRzaWRlIFNURU0gbWFqb3JzICgkXGJldGEgPSDiiJIwLjE3LCBwID0gLjAzOSQpLiBBY2FkZW1pYyAqKm1ham9ycyoqIGNhdGVnb3JpemVkIGFzIEhlYWx0aCBvciBPdGhlciBkaWQgbm90IHNob3cgc2lnbmlmaWNhbnQgcmVsYXRpb25zaGlwcyB3aXRoIGFueGlldHkgKCRwID4gLjA1JCkuDQoNClBzeWNob2xvZ2ljYWwgYW5kIGluc3RydWN0aW9uYWwgZmFjdG9ycyBkZW1vbnN0cmF0ZWQgbm90YWJsZSBhc3NvY2lhdGlvbnMgd2l0aCBtYXRoIGxlYXJuaW5nIGFueGlldHkuIEhpZ2hlciBsZXZlbHMgb2YgKipzZWxmLWVmZmljYWN5Kiogd2VyZSBzdHJvbmdseSBhc3NvY2lhdGVkIHdpdGggbG93ZXIgYW54aWV0eSAoJFxiZXRhID0g4oiSMC4zOSwgcCA8IC4wMDEkKSwgcmVwcmVzZW50aW5nIHRoZSBsYXJnZXN0IGVmZmVjdCBpbiB0aGUgbW9kZWwuIE1vcmUgZnJlcXVlbnQgdXNlIG9mIHRlY2hub2xvZ3ktc3VwcG9ydGVkIGxlYXJuaW5nICgkXGJldGEgPSDiiJIwLjEwLCBwIDwgLjAwMSQpIGFuZCAqKnRlYWNoZXItY2VudGVyZWQqKiBhcHByb2FjaGVzICgkXGJldGEgPSDiiJIwLjE4LCBwIDwgLjAwMSQpIHdpbGwgaGVscCByZWR1Y2UgYW54aWV0eSBsZXZlbHMuIEluIGNvbnRyYXN0LCBpbmNyZWFzZWQgcmVsaWFuY2Ugb24gKipyZXNvdXJjZS1iYXNlZCBsZWFybmluZyoqIHN0cmF0ZWdpZXMgd2FzIHBvc2l0aXZlbHkgYXNzb2NpYXRlZCB3aXRoIGFueGlldHkgKCRcYmV0YSA9IDAuMDksIHAgPSAuMDExJCkuIEFsdGhvdWdoICoqc3R1ZGVudC1jZW50ZXJlZCoqIGluc3RydWN0aW9uIHNob3dlZCBhIHBvc2l0aXZlIGFzc29jaWF0aW9uIHdpdGggYW54aWV0eSwgdGhpcyBlZmZlY3QgZGlkIG5vdCByZWFjaCBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2UgKCRcYmV0YSA9IDAuMDYsIHAgPSAuMDc0JCkuDQoNClRvZ2V0aGVyLCB0aGVzZSByZXN1bHRzIGRlbW9uc3RyYXRlIHRoYXQgY29uZmlkZW5jZSBpbiBvbmXigJlzIG1hdGhlbWF0aWNhbCBhYmlsaXR5IGFuZCBzcGVjaWZpYyBpbnN0cnVjdGlvbmFsIG1ldGhvZHMgcGxheSBhbiBpbXBvcnRhbnQgcm9sZSBpbiBzaGFwaW5nIHN0dWRlbnRz4oCZIG1hdGggbGVhcm5pbmcgYW54aWV0eS4gQXBwcm9hY2hlcyB0aGF0IHByb3ZpZGUgc3RydWN0dXJlZCBndWlkYW5jZeKAlHN1Y2ggYXMgdGVhY2hlci1jZW50ZXJlZCBkZWxpdmVyeSBhbmQgdGVjaG5vbG9neSBpbnRlZ3JhdGlvbuKAlGFwcGVhciB0byByZWR1Y2UgYW54aWV0eSwgd2hlcmVhcyBncmVhdGVyIGVtcGhhc2lzIG9uIGluZGVwZW5kZW50IHJlc291cmNlLWJhc2VkIGxlYXJuaW5nIG1heSBjb250cmlidXRlIHRvIGluY3JlYXNlZCBhbnhpZXR5Lg0KDQoNCiMgU3RydWN0dXJhbCBFcXVhdGlvbiBNb2RlbGluZyBBcHByb2FjaA0KDQoqKlN0cnVjdHVyYWwgZXF1YXRpb24gbW9kZWxpbmcgKFNFTSkqKiBpcyBhIGxpbmVhciBtb2RlbCBmcmFtZXdvcmsgdGhhdCBtb2RlbHMgYm90aCBzaW11bHRhbmVvdXMgcmVncmVzc2lvbiBlcXVhdGlvbnMgd2l0aCBsYXRlbnQgdmFyaWFibGVzLiAgTW9kZWxzIHN1Y2ggYXMgbGluZWFyIHJlZ3Jlc3Npb24sIG11bHRpdmFyaWF0ZSByZWdyZXNzaW9uLCBwYXRoIGFuYWx5c2lzLCBjb25maXJtYXRvcnkgZmFjdG9yIGFuYWx5c2lzLCBhbmQgc3RydWN0dXJhbCByZWdyZXNzaW9uIGNhbiBiZSB0aG91Z2h0IG9mIGFzIHNwZWNpYWwgY2FzZXMgb2YgU0VNLiBUaGUgZm9sbG93aW5nIHJlbGF0aW9uc2hpcHMgYXJlIHBvc3NpYmxlIGluIFNFTToNCg0KKiAqb2JzZXJ2ZWQgdG8gb2JzZXJ2ZWQgdmFyaWFibGVzKiAoJFxnYW1tYSQsIGUuZy4sIHJlZ3Jlc3Npb24pDQoqICpsYXRlbnQgdG8gb2JzZXJ2ZWQgdmFyaWFibGVzKiAoJFxsYW1iZGEkLCBlLmcuLCBjb25maXJtYXRvcnkgZmFjdG9yIGFuYWx5c2lzKQ0KKiAqbGF0ZW50IHRvIGxhdGVudCB2YXJpYWJsZXMqICgkXGdhbW1hLCBcYmV0YSQsIGUuZy4sIHN0cnVjdHVyYWwgcmVncmVzc2lvbikNCiANClNFTSB1bmlxdWVseSBlbmNvbXBhc3NlcyBib3RoIG1lYXN1cmVtZW50IGFuZCBzdHJ1Y3R1cmFsIG1vZGVscy4gVGhlIG1lYXN1cmVtZW50IG1vZGVsIHJlbGF0ZXMgb2JzZXJ2ZWQgdG8gbGF0ZW50IHZhcmlhYmxlcyBhbmQgdGhlIHN0cnVjdHVyYWwgbW9kZWwgcmVsYXRlcyBsYXRlbnQgdG8gbGF0ZW50IHZhcmlhYmxlcy4gDQoNCg0KIyMgTm90YXRpb25zIGFuZCBUZWNobmljYWwgVGVybXMgaW4gU0VNDQoNCg0KDQoqKlNvbWUgVGVjaG5pY2FsIFRlcm1zIGluIFNFTSoqOg0KDQoqICoqb2JzZXJ2ZWQgdmFyaWFibGUqKjogYSB2YXJpYWJsZSB0aGF0IGV4aXN0cyBpbiB0aGUgZGF0YSwgYS5rLmEgaXRlbSBvciBtYW5pZmVzdCB2YXJpYWJsZQ0KDQoqICoqbGF0ZW50IHZhcmlhYmxlKio6IGEgdmFyaWFibGUgdGhhdCBpcyBjb25zdHJ1Y3RlZCBhbmQgZG9lcyBub3QgZXhpc3QgaW4gdGhlIGRhdGENCg0KKiAqKmV4b2dlbm91cyB2YXJpYWJsZSoqOiBhbiBpbmRlcGVuZGVudCB2YXJpYWJsZSBlaXRoZXIgb2JzZXJ2ZWQgKHgpIG9yIGxhdGVudCAoJFx4aSQpIHRoYXQgZXhwbGFpbnMgYW4gZW5kb2dlbm91cyB2YXJpYWJsZQ0KDQoqICoqZW5kb2dlbm91cyB2YXJpYWJsZSoqOiBhIGRlcGVuZGVudCB2YXJpYWJsZSwgZWl0aGVyIG9ic2VydmVkICh5KSBvciBsYXRlbnQgKCRcZXRhJCkgdGhhdCBoYXMgYSBjYXVzYWwgcGF0aCBsZWFkaW5nIHRvIGl0DQoNCiogKiptZWFzdXJlbWVudCBtb2RlbCoqOiBhIG1vZGVsIHRoYXQgbGlua3Mgb2JzZXJ2ZWQgdmFyaWFibGVzIHdpdGggbGF0ZW50IHZhcmlhYmxlcw0KDQoqICoqaW5kaWNhdG9yKio6IGFuIG9ic2VydmVkIHZhcmlhYmxlIGluIGEgbWVhc3VyZW1lbnQgbW9kZWwgKGNhbiBiZSBleG9nZW5vdXMgb3IgZW5kb2dlbm91cykNCg0KKiAqKmZhY3RvcioqOiBhIGxhdGVudCB2YXJpYWJsZSBkZWZpbmVkIGJ5IGl0cyBpbmRpY2F0b3JzIChjYW4gYmUgZXhvZ2Vub3VzIG9yIGVuZG9nZW5vdXMpDQoNCiogKipsb2FkaW5nKio6IGEgcGF0aCBiZXR3ZWVuIGFuIGluZGljYXRvciBhbmQgYSBmYWN0b3INCg0KKiAqKnN0cnVjdHVyYWwgbW9kZWwqKjogYSBtb2RlbCB0aGF0IHNwZWNpZmllcyBjYXVzYWwgcmVsYXRpb25zaGlwcyBhbW9uZyBleG9nZW5vdXMgdmFyaWFibGVzIHRvIGVuZG9nZW5vdXMgdmFyaWFibGVzIChjYW4gYmUgb2JzZXJ2ZWQgb3IgbGF0ZW50KQ0KDQoqICoqcmVncmVzc2lvbiBwYXRoKio6IGEgcGF0aCBiZXR3ZWVuIGV4b2dlbm91cyBhbmQgZW5kb2dlbm91cyB2YXJpYWJsZXMgKGNhbiBiZSBvYnNlcnZlZCBvciBsYXRlbnQpDQoNCg0KDQojIyBTRU0gUGF0aCBNb2RlbA0KDQpBIHBhdGggbW9kZWwgc2VydmVzIGFzIHRoZSB2aXN1YWwgYW5kIG1hdGhlbWF0aWNhbCBibHVlcHJpbnQgZm9yIGEgU3RydWN0dXJhbCBFcXVhdGlvbiBNb2RlbCAoU0VNKS4gVGhpcyBkaWFncmFtIGVtcGxveXMgYSBzdGFuZGFyZGl6ZWQgbm90YXRpb24gdG8gcmVwcmVzZW50IGh5cG90aGVzaXplZCByZWxhdGlvbnNoaXBzIGJldHdlZW4gdmFyaWFibGVzLiBUaGUgc3BlY2lmaWMgbW9kZWwgdG8gYmUgdGVzdGVkLCB3aGljaCBleGFtaW5lcyB0aGUgY29tcGxleCBzdHJ1Y3R1cmFsIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBlbmRvZ2Vub3VzIGFuZCBleG9nZW5vdXMgdmFyaWFibGVzLCBoYXMgdGhlIGZvbGxvd2luZyBzdHJ1Y3R1cmU6DQoNCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGg9IjcwJSJ9DQppbmNsdWRlX2dyYXBoaWNzKCJIeXBvdGhldGljYWxTRU0ucG5nIikNCmBgYA0KDQpUbyBiZXR0ZXIgdW5kZXJzdGFuZCB0aGUgYWR2YW50YWdlcyBhbmQgZGlzYWR2YW50YWdlcyBvZiBTdHJ1Y3R1cmFsIEVxdWF0aW9uIE1vZGVsaW5nIChTRU0pIGZvciBhbmFseXppbmcgY29tcGxleCByZWxhdGlvbnNoaXBz4oCUc3VjaCBhcyB0aG9zZSBiZXR3ZWVuIGxhdGVudCB2YXJpYWJsZXMgbGlrZSBtYXRoIGV2YWx1YXRpb24gYW5kIGxlYXJuaW5nIGFueGlldHkuIHdlIHdpbGwgYnJpZWZseSBkZXNjcmliZSBpdHMgbWF0aGVtYXRpY2FsIGZvcm11bGF0aW9uIGFuZCBNTEUgb2YgYWxsIG1vZGVsIHBhcmFtZXRlcnMgdXNpbmcgdGhlIGFib3ZlIGh5cG90aGV0aWNhbCBTRU0gcGF0aCBtb2RlbCBpbiB0aGUgYXBwZW5kaXguDQoNCg0KDQojIyBTRU0gSW1wbGVtZW50YXRpb24NCg0KV2UgdXNlIHRoZSBSIGBsYXZhYW5gIGxpYnJhcnkgdG8gaW1wbGVtZW50IHRoZSBTRU0gdG8gYXNzZXNzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBtYXRoIGV2YWx1YXRpb24sIGxlYXJuaW5nIGFueGlldHksIGFuZCByZWxhdGVkIGV4b2dlbm91cyB2YXJpYWJsZXMuIFRoZSBvdXRwdXQgcHJlc2VudHMgcmVzdWx0cyBiYXNlZCBvbiBzdGFuZGFyZGl6ZWQgdmFyaWFibGVzLiBUaGUgaW50ZXJwcmV0YXRpb24gb2YgdGhlIHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzIGlzIHNpbWlsYXIgdG8gdGhhdCBpbiBhIHJlZ3VsYXIgcmVncmVzc2lvbiBtb2RlbCwgaW5kaWNhdGluZyB0aGUgY2hhbmdlIGluIHRoZSBvdXRjb21lIChpbiBzdGFuZGFyZCBkZXZpYXRpb25zKSBmb3IgYSBvbmUtc3RhbmRhcmQtZGV2aWF0aW9uIGluY3JlYXNlIGluIGEgcHJlZGljdG9yLiANCg0KDQoqKlF1aWNrIFJlZmVyZW5jZSBvZiBgbGF2YWFuYCBTeW50YXgqKg0KDQoqIGB+IHByZWRpY3RgLCB1c2VkIGZvciByZWdyZXNzaW9uIG9mIG9ic2VydmVkIG91dGNvbWUgdG8gb2JzZXJ2ZWQgcHJlZGljdG9ycyAoZS5nLiwgeSB+IHgpDQoqIGAxPX4gaW5kaWNhdG9yMWAsIHVzZWQgZm9yIGxhdGVudCB2YXJpYWJsZSB0byBvYnNlcnZlZCBpbmRpY2F0b3IgaW4gZmFjdG9yIGFuYWx5c2lzIG1lYXN1cmVtZW50IG1vZGVscyAoZS5nLiwgYGYgPX4gcSArIHIgKyBzYCkNCiogYGB+fmAgY292YXJpYW5jZSAoZS5nLiwgYHggfn4geGApDQoqIGB+MWAgaW50ZXJjZXB0IG9yIG1lYW4gKGUuZy4sIGB4IH4gMWAgZXN0aW1hdGVzIHRoZSBtZWFuIG9mIHZhcmlhYmxlIHgpDQoqIGAxKmAgZml4ZXMgcGFyYW1ldGVyIG9yIGxvYWRpbmcgdG8gb25lIChlLmcuLCBgZiA9fiAxKnFgKQ0KKiBgTkEqYCBmcmVlcyBwYXJhbWV0ZXIgb3IgbG9hZGluZyAodXNlZnVsIHRvIG92ZXJyaWRlIGRlZmF1bHQgbWFya2VyIG1ldGhvZCwgKGUuZy4sIGBmID1+IE5BKnFgKQ0KKiBgYSpgIGxhYmVscyB0aGUgcGFyYW1ldGVyIOKAmGHigJksIHVzZWQgZm9yIG1vZGVsIGNvbnN0cmFpbnRzIChlLmcuLCBgZiA9fiBhKnFgKQ0KDQoNCg0KYGBge3J9DQpBbnhpZXR5Lm1lYSA8LSBDb21wLkFueGlldHlbLCBjKCJBTUFTLjIiLCAiQU1BUy40IiwgIkFNQVMuNSIsICAiQU1BUy44IildDQpBbnhpZXR5Lm1sYSA8LSBDb21wLkFueGlldHlbLCBjKCJBTUFTLjEiLCAiQU1BUy4zIiwgIkFNQVMuNiIsICJBTUFTLjciLCAiQU1BUy45IildDQpuYW1lcyhBbnhpZXR5Lm1lYSkgPC0gYygiTUVBMiIsICJNRUE0IiwgIk1FQTUiLCAgIk1FQTgiKSAgDQpuYW1lcyhBbnhpZXR5Lm1sYSkgPC0gYygiTUxBMSIsICJNTEEzIiwgIk1MQTYiLCAiTUxBNyIsICJNTEE5IikNCmZhY3Rvci5uYW1lcyA8LSBjKCJUZWNobm9sb2d5Lnd0LnBjYSIsICJTZWxmRWZmaWNhY3kud3QucGNhIiwgIkVuZ2FnZS53dC5wY2EiLCAic2V4IiwNCiAgICAgICAgICAgICAgICAgICJUZWFjaGVyLmN0cmQud3QucGNhIiwgIlN0dWRlbnQuY3RyZC53dC5wY2EiLCAiUmVzb3VyY2Uud3QucGNhIikNCiMjDQpmYWN0b3IudmFyIDwtIEFueGlldHkuQW5hbHl0aWMuRGF0YVssIGZhY3Rvci5uYW1lc10NCm5hbWVzKGZhY3Rvci52YXIpIDwtIGMoIlRlY2giLCAiRWZmaWNhY3kiLCAiRW5nYWdlIiwgImdlbmRlciIsDQogICAgICAgICAgICAgICAgICAiVGVhY2hlci5jdHJkIiwgIlN0dWRlbnQuY3RyZCIsICJSZXNvdXJjZSIpDQoNCiMjIyBzdHJhdGVnaWVzIHZhcg0Kc3RyYXRneS52YXIgPC1jKCJDb29wb3JhdGl2ZS53dC5wY2EiLCAiRGVkdWN0aXZlLnd0LnBjYSIsICJEZW1vbnN0cmF0aW9uLnd0LnBjYSIsICJJbmR1Y3RpdmUud3QucGNhIiwiSW50ZWdyYXRpdmUud3QucGNhIiAsIkxlY3R1cmVUeXBlLnd0LnBjYSIsICJSZXBldGl0aXZlLnd0LnBjYSIgKQ0Kc3RyYXRlZ3kubmFtZSA8LSBjKCJDb29wIiwgIkRlZHVjIiwgIkRlbW9uIiwgIkluZHVjIiwiSW50ZWciICwiTGVjdCIsICJSZXBldCIgKQ0KdGVhY2hpbmdzdHJhdGVneSA8LSBBbnhpZXR5LkFuYWx5dGljLkRhdGFbLCBzdHJhdGd5LnZhcl0NCm5hbWVzKHRlYWNoaW5nc3RyYXRlZ3kpIDwtIHN0cmF0ZWd5Lm5hbWUgDQpTRU0uZGF0YSA8LSBjYmluZChBbnhpZXR5Lm1lYSwgQW54aWV0eS5tbGEsIGZhY3Rvci52YXIsdGVhY2hpbmdzdHJhdGVneSApDQoNCiMjIyAgU0VNIG1vZGVscw0KDQpTRU1Nb2RlbCA8LQ0KJyBFdmFsLkFueGlldHkgPX4gIE1FQTIgKyBNRUE0ICsgTUVBNSArIE1FQTggICMjIG1lYXN1cmVtZW50IG1vZGVsIGZvciBFdmFsLkFueGlldHkNCiAgTGVhcm4uQW54aWV0eSA9fiBNTEExICsgTUxBMyArIE1MQTYgKyBNTEE3ICsgTUxBOSAgICMjIG1lYXN1cmVtZW50IG1vZGVsIGZvciBMZWFybi5BbnhpZXR5IA0KICBUZWFjaGVyQ3RyZCA9fiBEZWR1YyArIExlY3QgKyBEZW1vbiArIFJlcGV0ICAjIFRlYWNoZXIgY2VudGVyZWQNCiAgU3R1ZGVudEN0cmQgPX4gQ29vcCArIEluZHVjICsgSW50ZWcgICMgU3R1ZGVudCBjZW50ZXJlZA0KICBFdmFsLkFueGlldHkgfiBUZWNoICsgRWZmaWNhY3kgKyBFbmdhZ2UgKyBnZW5kZXIgKyBUZWFjaGVyQ3RyZCArIFN0dWRlbnRDdHJkICsgUmVzb3VyY2UgICAgIyMgRXZhbC5BbnhpZXR5IGFzIGFuIG91dGNvbWUNCiAgTGVhcm4uQW54aWV0eSB+IFRlY2ggKyBFZmZpY2FjeSArIEVuZ2FnZSArIGdlbmRlciArIFRlYWNoZXJDdHJkKyBTdHVkZW50Q3RyZCArIFJlc291cmNlICAgICMjIExlYXJuLkFueGlldHkgYXMgYW4gb3V0Y29tZQ0KICBFdmFsLkFueGlldHkgfn4gTGVhcm4uQW54aWV0eSAgICAgIyMgY29ycmVsYXRpb24gYmV0d2VlbiBFdmFsLkFueGlldHkgYW5kIExlYXJuLkFueGlldHkgDQonDQogDQpvdXRwdXQgPC0gc2VtKG1vZGVsID0gU0VNTW9kZWwsIGRhdGEgPSBTRU0uZGF0YSwgc3RkLmx2ID0gVFJVRSwNCiAgICAgICAgICAgICAgbWlzc2luZyA9ICJmaW1sIiwgbWltaWMgPSAiTXBsdXMiKQ0KcmVzdWx0cyA8LSBzdW1tYXJ5KG91dHB1dCwgc3RhbmRhcmRpemVkID0gVFJVRSwgZml0Lm1lYXN1cmVzID0gVFJVRSkNCg0KYGBgDQoNClRoZSBjb21wb25lbnQgcmVncmVzc2lvbiBhbnMgbGF0ZW50IG1vZGVscyBpbiB0aGUgU0VNIGFyZSBzcGVjaWZpZWQgaW4gdGhlIGZvbGxvd2luZy4NCg0KYGBgDQogICMjIG1lYXN1cmVtZW50IG1vZGVsIGZvciBFdmFsLkFueGlldHkNCiAgRXZhbC5BbnhpZXR5ID1+ICBNRUEyICsgTUVBNCArIE1FQTUgKyBNRUE4ICAgICAgICAgICAgDQogICMjIG1lYXN1cmVtZW50IG1vZGVsIGZvciBMZWFybi5BbnhpZXR5IA0KICBMZWFybi5BbnhpZXR5ID1+IE1MQTEgKyBNTEEzICsgTUxBNiArIE1MQTcgKyBNTEE5ICANCiAgIyBMYXRlbnQgcmVncmVzc2lvbiBvZiB0ZWFjaGluZyBTdHJhdGVnaWVzDQogIFRlYWNoZXJDdHJkID1+IERlZHVjICsgTGVjdCArIERlbW9uICsgUmVwZXQgICMgVGVhY2hlciBjZW50ZXJlZA0KICBTdHVkZW50Q3RyZCA9fiBDb29wICsgSW5kdWMgKyBJbnRlZyAgIyBTdHVkZW50IGNlbnRlcmVkDQogICMjIEV2YWwuQW54aWV0eSBhcyBhbiBvdXRjb21lDQogIEV2YWwuQW54aWV0eSB+IFRlY2ggKyBFZmZpY2FjeSArIEVuZ2FnZSArIGdlbmRlciArIFRlYWNoZXIuY3RyZCArIFN0dWRlbnQuY3RyZCArIFJlc291cmNlICsgcmFjZSAgIA0KICAjIyBMZWFybi5BbnhpZXR5IGFzIGFuIG91dGNvbWUNCiAgTGVhcm4uQW54aWV0eSB+IFRlY2ggKyBFZmZpY2FjeSArIEVuZ2FnZSArIGdlbmRlciArIFRlYWNoZXIuY3RyZCArIFN0dWRlbnQuY3RyZCArIFJlc291cmNlICsgcmFjZSAgDQogIEV2YWwuQW54aWV0eSB+fiBMZWFybi5BbnhpZXR5ICAgICAjIyBjb3JyZWxhdGlvbiBiZXR3ZWVuIEV2YWwuQW54aWV0eSBhbmQgTGVhcm4uQW54aWV0eSANCmBgYA0KDQpUaGUga2V5IGdvb2RuZXNzLW9mLWZpdCBzdGF0aXN0aWNzIGFuZCBlc3RpbWF0ZWQgcGFyYW1ldGVycyBhcmUgc3VtbWFyaXplZCBpbiB0aGUgZm9sbG93aW5nLg0KDQoNCmBgYHtyfQ0KaW50ZXJwcmV0X2ZpdCA8LSBmdW5jdGlvbihmaXRfb2JqKSB7DQogIG1lYXN1cmVzIDwtIGZpdE1lYXN1cmVzKGZpdF9vYmopDQogIA0KICAjY2F0KCI9PT0gU0VNIE1PREVMIEZJVCBBU1NFU1NNRU5UID09PVxuIikNCiAgY2F0KHNwcmludGYoIkNoaS1TcXVhcmU6IM+HwrIoJWQpID0gJS4yZiwgcCA9ICUuM2ZcbiIsIA0KICAgICAgICAgICAgICBtZWFzdXJlc1siZGYiXSwgbWVhc3VyZXNbImNoaXNxIl0sIG1lYXN1cmVzWyJwdmFsdWUiXSkpDQogIGNhdChzcHJpbnRmKCJDRkk6ICUuM2YgJXNcbiIsIG1lYXN1cmVzWyJjZmkiXSwNCiAgICAgICAgICAgICAgaWZlbHNlKG1lYXN1cmVzWyJjZmkiXSA+PSAwLjk1LCAiKEV4Y2VsbGVudCkiLA0KICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKG1lYXN1cmVzWyJjZmkiXSA+PSAwLjkwLCAiKEFjY2VwdGFibGUpIiwgIihQb29yKSIpKSkpDQogIGNhdChzcHJpbnRmKCJUTEk6ICUuM2YgJXNcbiIsIG1lYXN1cmVzWyJ0bGkiXSwNCiAgICAgICAgICAgICAgaWZlbHNlKG1lYXN1cmVzWyJ0bGkiXSA+PSAwLjk1LCAiKEV4Y2VsbGVudCkiLA0KICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKG1lYXN1cmVzWyJ0bGkiXSA+PSAwLjkwLCAiKEFjY2VwdGFibGUpIiwgIihQb29yKSIpKSkpDQogIGNhdChzcHJpbnRmKCJSTVNFQTogJS4zZiBbOTAlJSBDSTogJS4zZiwgJS4zZl0gJXNcbiIsIA0KICAgICAgICAgICAgICBtZWFzdXJlc1sicm1zZWEiXSwgbWVhc3VyZXNbInJtc2VhLmNpLmxvd2VyIl0sIG1lYXN1cmVzWyJybXNlYS5jaS51cHBlciJdLA0KICAgICAgICAgICAgICBpZmVsc2UobWVhc3VyZXNbInJtc2VhIl0gPD0gMC4wNiwgIihFeGNlbGxlbnQpIiwNCiAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShtZWFzdXJlc1sicm1zZWEiXSA8PSAwLjA4LCAiKEFjY2VwdGFibGUpIiwgIihQb29yKSIpKSkpDQogIGNhdChzcHJpbnRmKCJTUk1SOiAlLjNmICVzXG4iLCBtZWFzdXJlc1sic3JtciJdLA0KICAgICAgICAgICAgICBpZmVsc2UobWVhc3VyZXNbInNybXIiXSA8PSAwLjA4LCAiKEV4Y2VsbGVudCkiLA0KICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKG1lYXN1cmVzWyJzcm1yIl0gPD0gMC4xMCwgIihBY2NlcHRhYmxlKSIsICIoUG9vcikiKSkpKQ0KfQ0KDQojIyMNCnJlcG9ydF9zZW0gPC0gZnVuY3Rpb24oZml0LCBtb2RlbF9uYW1lID0gIlRoZSBTRU0iKSB7DQogIA0KICAjIEZpdCBtZWFzdXJlcw0KICBmaXRfbWVhcyA8LSBmaXRNZWFzdXJlcyhmaXQsIGMoImNoaXNxIiwgImRmIiwgInB2YWx1ZSIsICJjZmkiLCAidGxpIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJybXNlYSIsICJybXNlYS5jaS5sb3dlciIsICJybXNlYS5jaS51cHBlciIsICJzcm1yIikpDQogIA0KICAjIFBhcmFtZXRlcnMNCiAgcGFyYW1zIDwtIHBhcmFtZXRlckVzdGltYXRlcyhmaXQpDQogIHN0ZF9wYXJhbXMgPC0gc3RhbmRhcmRpemVkU29sdXRpb24oZml0KQ0KICANCiAgY2F0KCI9PT0gU1RSVUNUVVJBTCBFUVVBVElPTiBNT0RFTElORyBSRVNVTFRTID09PVxuXG4iKQ0KICBjYXQoIk1PREVMIEZJVDpcbiIpDQogIA0KICAjIFVzZSB0aGUgZnVuY3Rpb24NCiAgaW50ZXJwcmV0X2ZpdChvdXRwdXQpDQogIGNhdCgiXG5cbiIpDQogICMgU2lnbmlmaWNhbnQgc3RydWN0dXJhbCBwYXRocw0KICBzaWdfcGF0aHMgPC0gc3RkX3BhcmFtc1tzdGRfcGFyYW1zJG9wID09ICJ+IiAmIHN0ZF9wYXJhbXMkcHZhbHVlIDwgMC4xLCBdDQogIGlmIChucm93KHNpZ19wYXRocykgPiAwKSB7DQogICAgY2F0KCJTSUdOSUZJQ0FOVCBTVFJVQ1RVUkFMIFBBVEhTOlxuIikNCiAgICBmb3IgKGkgaW4gMTpucm93KHNpZ19wYXRocykpIHsNCiAgICAgIGNhdChzcHJpbnRmKCItICVzIOKGkiAlczogzrIgPSAlLjJmLCBwID0gJS4zZlxuIiwNCiAgICAgICAgICAgICAgICAgIHNpZ19wYXRocyRyaHNbaV0sIHNpZ19wYXRocyRsaHNbaV0sDQogICAgICAgICAgICAgICAgICBzaWdfcGF0aHMkZXN0W2ldLCBzaWdfcGF0aHMkcHZhbHVlW2ldKSkNCiAgICB9DQogICAgY2F0KCJcbiIpDQogIH0NCiAgDQogICMgZmFjdG9yIGxvYWRpbmcgZm9yIGxhdGVudCB2YXJpYWJsZXMNCiAgY2F0KCJcblxuRkFDVE9SIExPQURJTkdTXG5cbiIpDQogIA0KICBwcmludChzdGRfcGFyYW1zW3N0ZF9wYXJhbXMkb3AgPT0gIj1+IiwgXSkNCiAgDQogICMjIyMjDQogICMgUi1zcXVhcmVkDQogIHIyIDwtIGluc3BlY3QoZml0LCAicjIiKQ0KICBpZiAobGVuZ3RoKHIyKSA+IDApIHsNCiAgICBjYXQoIlZBUklBTkNFIEVYUExBSU5FRCAoUsKyKTpcblxuIikNCiAgICBmb3IgKGkgaW4gMTpsZW5ndGgocjIpKSB7DQogICAgICBjYXQoc3ByaW50ZigiLSAlczogJS4xZiUlXG4iLCBuYW1lcyhyMilbaV0sIHIyW2ldICogMTAwKSkNCiAgICB9DQogIH0NCiAgDQogICMjIFJlZ3Jlc3Npb24gY29lZmZpY2llbnRzDQogIA0KICBjYXQoIlxuXG5DT0VGRklDSUVOVFMgT0YgUkVHUkVTU0lPTlxuXG4iKQ0KICANCiAgcHJpbnQoc3RkX3BhcmFtc1tzdGRfcGFyYW1zJG9wID09ICJ+IiwgXSkNCiAgDQogICAgICMgQ292YXJpYW5jZSBiZXR3ZWVuIE1hdGggQW54aWV0aWVzDQogICAgICAjcGFyYW1fZXN0IDwtIHBhcmFtZXRlckVzdGltYXRlcyhmaXQpDQogICAgIGNvdl9sYXRlbnQgPC0gc3RkX3BhcmFtc1sNCiAgICAgICAgICAgICAgc3RkX3BhcmFtcyRsaHMgPT0gIk1hdGhFdmFsIiAmIA0KICAgICAgICAgICAgICBzdGRfcGFyYW1zJHJocyA9PSAiTGVhcm5BbngiICYgDQogICAgICAgICAgICAgIHN0ZF9wYXJhbXMkb3AgPT0gIn5+IiwNCiAgICAgICAgICBdDQogICAgICMjIw0KICAgICBjYXQoIlxuXG5DT1ZBUklBTkNFIDpcbiIpDQogICAgIGxhdGVudF9jb3ZfbWF0cml4IDwtIGxhdkluc3BlY3QoZml0LCAiZXN0IikkcHNpDQogICAgIGNvdl9vdXQgPC0gbGF0ZW50X2Nvdl9tYXRyaXhbIkxlYXJuLkFueGlldHkiLCAiRXZhbC5BbnhpZXR5Il0NCiAgICAgY2F0KCItIExlYXJuLkFueGlldHkgYW5kIEV2YWwuQW54aWV0eToiLCBjb3Zfb3V0KQ0KfQ0KDQojIFVzZSB0aGUgZnVuY3Rpb24NCnJlcG9ydF9zZW0ob3V0cHV0LCAiTWF0aCBBbnhpZXR5IikNCmBgYA0KDQpUaGUgcmVncmVzc2lvbiBjb2VmZmljaWVudHMgYW5kIGZhY3RvciBsb2FkaW5ncyBpbiB0aGUgYWJvdmUgdGFibGUgYXJlIHN1bW1hcml6ZWQgaW4gdGhlIGZvbGxvd2luZyBTRU0gcGF0aCBkaWFncmFtIGdlbmVyYXRlZCB1c2luZyBgbGF2YWFuUGxvdGAgZnVuY3Rpb24uICANCg0KYGBge3J9DQpsYXZhYW5QbG90KG1vZGVsID0gb3V0cHV0LA0KICAgICAgICAgICBjb2VmcyA9IFRSVUUsDQogICAgICAgICAgIHN0YW5kID0gVFJVRSwNCiAgICAgICAgICAgc3RhcnMgPSBjKCJyZWdyZXNzIikpICAjIEFkZCBzaWduaWZpY2FuY2Ugc3RhcnMNCmBgYA0KDQpUaGUgcGF0aCBkaWFncmFtIGdlbmVyYXRlZCBieSBSIGZvciB0aGUgU0VNIGFuYWx5c2lzIGlzIG5vdCBlYXN5IHRvIHJlYWQuIFRoZXJlZm9yZSwgd2Ugc2tldGNoZWQgYSBuZXcgcGF0aCBkaWFncmFtIHRoYXQgaW5jbHVkZXMgb25seSB0aGUgc2lnbmlmaWNhbnQgcmVncmVzc2lvbiBjb2VmZmljaWVudHMgYW5kIGZhY3RvciBsb2FkaW5ncy4NCg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aD0iNzAlIn0NCmluY2x1ZGVfZ3JhcGhpY3MoIkZpdHRlZGxTRU0ucG5nIikNCmBgYA0KDQojIyBSZXN1bHRzIGFuZCBEaXNjdXNzaW9uIG9mIFNFTSBBbmx5c2lzDQoNCiMjIyBSZXN1bHRzDQoNClRoZSBoeXBvdGhlc2l6ZWQgc3RydWN0dXJhbCBlcXVhdGlvbiBtb2RlbCBkZW1vbnN0cmF0ZWQgYW4gYWNjZXB0YWJsZSBmaXQgdG8gdGhlIGRhdGE6ICRcY2hpXjIoMTY4KSA9IDY2NC43NSwgcCA8IC4wMDEkOyAkQ0ZJID0gMC45Mjc7IFRMSSA9IDAuOTEzJDsgJFJNU0VBID0gMC4wNjUgKDkwJSBDSSBbMC4wNjAsIDAuMDcwXSkkOyBhbmQgJFNSTVIgPSAwLjA3MCQgVGhlc2UgZml0IGluZGljZXMgaW5kaWNhdGUgdGhhdCB0aGUgcHJvcG9zZWQgbW9kZWwgYWRlcXVhdGVseSByZXByZXNlbnRzIHRoZSBvYnNlcnZlZCBkYXRhLCB3aXRoIHZhbHVlcyBtZWV0aW5nIG9yIGV4Y2VlZGluZyBjb252ZW50aW9uYWwgdGhyZXNob2xkcyBmb3IgYWNjZXB0YWJsZSBtb2RlbCBmaXQuDQoNClNldmVyYWwgc2lnbmlmaWNhbnQgc3RydWN0dXJhbCBwYXRocyBlbWVyZ2VkLiAqKlRlY2hub2xvZ3kqKiB1c2Ugd2FzIGEgc2lnbmlmaWNhbnQgbmVnYXRpdmUgcHJlZGljdG9yIG9mIGJvdGggZXZhbHVhdGlvbiBhbnhpZXR5ICgkXGJldGEgPSDigJMwLjEzLCBwIDwgLjAwMSQpIGFuZCBsZWFybmluZyBhbnhpZXR5ICgkXGJldGEgPSDigJMwLjIwLCBwIDwgLjAwMSQpLCBzdWdnZXN0aW5nIHRoYXQgZ3JlYXRlciB0ZWNobm9sb2dpY2FsIHByb2ZpY2llbmN5IG9yIGludGVncmF0aW9uIHdhcyBhc3NvY2lhdGVkIHdpdGggcmVkdWNlZCBhbnhpZXR5IGluIGJvdGggY29udGV4dHMuIFNpbWlsYXJseSwgc2VsZi1lZmZpY2FjeSBuZWdhdGl2ZWx5IHByZWRpY3RlZCBldmFsdWF0aW9uIGFueGlldHkgKCRcYmV0YSA9IOKAkzAuNDcsIHAgPCAuMDAxJCkgYW5kIGxlYXJuaW5nIGFueGlldHkgKCRcYmV0YSA9IOKAkzAuNDIsIHAgPCAuMDAxJCksIGluZGljYXRpbmcgdGhhdCBpbmRpdmlkdWFscyB3aXRoIGhpZ2hlciBzZWxmLWVmZmljYWN5IGV4cGVyaWVuY2VkIGxvd2VyIGxldmVscyBvZiBhbnhpZXR5Lg0KDQoqKkdlbmRlcioqIGFsc28gaGFkIGEgc2lnbmlmaWNhbnQgZWZmZWN0IG9uIGV2YWx1YXRpb24gYW54aWV0eSAoJFxiZXRhID0g4oCTMC4xMywgcCA8IC4wMDEkKSwgaW1wbHlpbmcgcG90ZW50aWFsIGdlbmRlci1iYXNlZCBkaWZmZXJlbmNlcyBpbiBldmFsdWF0aW9uLXJlbGF0ZWQgYXBwcmVoZW5zaW9uLiBBbHRob3VnaCAqKnN0dWRlbnQtY2VudGVyZWQgaW5zdHJ1Y3Rpb24qKiB3YXMgbWFyZ2luYWxseSByZWxhdGVkIHRvIGxlYXJuaW5nIGFueGlldHkgKCRcYmV0YSA9IOKAkzAuNTEsIHAgPSAuMDU5JCksICoqcmVzb3VyY2UgYXZhaWxhYmlsaXR5KiogcG9zaXRpdmVseSBwcmVkaWN0ZWQgbGVhcm5pbmcgYW54aWV0eSAoJFxiZXRhID0gMC4xMiwgcCA9IC4wMDEkKSwgaW5kaWNhdGluZyB0aGF0IGFjY2VzcyB0byBhZGRpdGlvbmFsIHJlc291cmNlcyBtYXkgbm90IHVuaWZvcm1seSBhbGxldmlhdGUgYW54aWV0eSBhbmQgY291bGQsIGluIHNvbWUgY29udGV4dHMsIGNvbnRyaWJ1dGUgdG8gKmluY3JlYXNlZCBwcmVzc3VyZSogb3IgKmNvZ25pdGl2ZSBsb2FkKi4gT3RoZXIgaHlwb3RoZXNpemVkIHBhdGhzIChlLmcuLCAqKmVuZ2FnZW1lbnQqKiwgKip0ZWFjaGVyLWNlbnRlcmVkIGFwcHJvYWNoZXMqKikgd2VyZSBub3Qgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCAoYWxsICRwID4gLjA1JCkuDQoNCkFsbCBvYnNlcnZlZCBpbmRpY2F0b3JzIGxvYWRlZCBzaWduaWZpY2FudGx5IG9udG8gdGhlaXIgcmVzcGVjdGl2ZSBsYXRlbnQgY29uc3RydWN0cyAoYWxsICRwIDwgLjAwMSQpLCB3aXRoIHN0YW5kYXJkaXplZCBmYWN0b3IgbG9hZGluZ3MgcmFuZ2luZyBmcm9tIDAuNTEgdG8gMC44OCwgc3VwcG9ydGluZyBjb25zdHJ1Y3QgdmFsaWRpdHkuIEZvciBFdmFsdWF0aW9uIEFueGlldHksIHRoZSBzdHJvbmdlc3QgaW5kaWNhdG9ycyB3ZXJlICoqTUVBMioqICgkXGxhbWJkYSA9IDAuODgzJCkgYW5kICoqTUVBNCoqICgkXGxhbWJkYSA9IDAuODU3JCkuIEZvciBMZWFybmluZyBBbnhpZXR5LCB0aGUgaGlnaGVzdCBsb2FkaW5ncyB3ZXJlIG9ic2VydmVkIGZvciAqKk1MQTkqKiAoJFxsYW1iZGEgPSAwLjcyNSQpIGFuZCAqKk1MQTMqKiAoJFxsYW1iZGEgPSAwLjcxNCQpLiBBbW9uZyB0ZWFjaGluZyBhcHByb2FjaGVzLCAqKlRlYWNoZXItQ2VudGVyZWQgSW5zdHJ1Y3Rpb24qKiB3YXMgYmVzdCByZXByZXNlbnRlZCBieSAqKkRlZHVjdGl2ZSoqICgkXGxhbWJkYSA9IDAuODg2JCkgYW5kICoqTGVjdHVyZSoqICgkXGxhbWJkYSA9IDAuODY4JCkgbWV0aG9kcywgd2hpbGUgKipTdHVkZW50LUNlbnRlcmVkIEluc3RydWN0aW9uKiogd2FzIGJlc3QgcmVmbGVjdGVkIGJ5ICoqSW5kdWN0aXZlKiogKCRcbGFtYmRhID0gMC44NjIkKSBhbmQgKipDb29wZXJhdGl2ZSoqICgkXGxhbWJkYSA9IDAuNzMzJCkgc3RyYXRlZ2llcy4NCg0KVGhlIG1vZGVsIGFjY291bnRlZCBmb3IgMzQuOSUgb2YgdGhlIHZhcmlhbmNlIGluIGV2YWx1YXRpb24gYW54aWV0eSBhbmQgMzMuNCUgb2YgdGhlIHZhcmlhbmNlIGluIGxlYXJuaW5nIGFueGlldHksIGluZGljYXRpbmcgbW9kZXJhdGUgZXhwbGFuYXRvcnkgcG93ZXIuIFRoZSBjb3ZhcmlhbmNlIGJldHdlZW4gZXZhbHVhdGlvbiBhbnhpZXR5IGFuZCBsZWFybmluZyBhbnhpZXR5IHdhcyBzaWduaWZpY2FudCBhbmQgcG9zaXRpdmUgKCRyID0gMC41MyQpLCBzdWdnZXN0aW5nIHRoYXQgd2hpbGUgZGlzdGluY3QsIHRoZXNlIHR3byBmb3JtcyBvZiBhbnhpZXR5IGFyZSBtb2RlcmF0ZWx5IGNvcnJlbGF0ZWQuDQoNCk92ZXJhbGwsIHRoZSByZXN1bHRzIGhpZ2hsaWdodCB0aGUgcGl2b3RhbCByb2xlIG9mICoqc2VsZi1lZmZpY2FjeSoqIGFuZCAqKnRlY2hub2xvZ3kgdXNlKiogaW4gbWl0aWdhdGluZyBib3RoIGV2YWx1YXRpb24gYW5kIGxlYXJuaW5nLXJlbGF0ZWQgYW54aWV0eS4gVGhlc2UgZmluZGluZ3MgYWxpZ24gd2l0aCBwcmlvciByZXNlYXJjaCBlbXBoYXNpemluZyB0aGF0IGNvbmZpZGVuY2UgaW4gb25l4oCZcyBhYmlsaXRpZXMgYW5kIGZhbWlsaWFyaXR5IHdpdGggZGlnaXRhbCB0b29scyBjYW4gZW5oYW5jZSBwZXJjZWl2ZWQgY29udHJvbCBhbmQgcmVkdWNlIGFueGlldHkgaW4gYWNhZGVtaWMgY29udGV4dHMuIFRoZSBtYXJnaW5hbCBpbmZsdWVuY2Ugb2YgKipzdHVkZW50LWNlbnRlcmVkIGFwcHJvYWNoZXMqKiBzdWdnZXN0cyBwb3RlbnRpYWwgYmVuZWZpdHMgZm9yIHJlZHVjaW5nIGxlYXJuaW5nIGFueGlldHkgdGhyb3VnaCBhY3RpdmUgYW5kIHBhcnRpY2lwYXRvcnkgbGVhcm5pbmcgZW52aXJvbm1lbnRzLCBhbHRob3VnaCB0aGUgZWZmZWN0IGRpZCBub3QgcmVhY2ggY29udmVudGlvbmFsIHNpZ25pZmljYW5jZS4gVGhlIHBvc2l0aXZlIGFzc29jaWF0aW9uIGJldHdlZW4gKipyZXNvdXJjZSBhdmFpbGFiaWxpdHkqKiBhbmQgYW54aWV0eSBtYXkgaW5kaWNhdGUgdGhhdCB3aGlsZSBhY2Nlc3MgdG8gbWF0ZXJpYWxzIHN1cHBvcnRzIGxlYXJuaW5nLCBpdCBjYW4gYWxzbyBpbnRyb2R1Y2UgaW5mb3JtYXRpb24gb3ZlcmxvYWQgb3IgcGVyZm9ybWFuY2UgZXhwZWN0YXRpb25zIHRoYXQgaGVpZ2h0ZW4gYW54aWV0eS4gVG9nZXRoZXIsIHRoZXNlIGZpbmRpbmdzIHVuZGVyc2NvcmUgdGhlIG11bHRpZmFjZXRlZCBuYXR1cmUgb2YgYWNhZGVtaWMgYW54aWV0eSBhbmQgcG9pbnQgdG8gdGhlIGltcG9ydGFuY2Ugb2YgZm9zdGVyaW5nIGVmZmljYWN5IGFuZCB0ZWNobm9sb2dpY2FsIHJlYWRpbmVzcyB0byBjcmVhdGUgc3VwcG9ydGl2ZSBsZWFybmluZyBlbnZpcm9ubWVudHMuDQoNClRoZXNlIGZpbmRpbmdzIGNvbGxlY3RpdmVseSBpbmZvcm0gdGhlIHN1YnNlcXVlbnQgZGlzY3Vzc2lvbiBvbiBob3cgKippbnN0cnVjdGlvbmFsIGRlc2lnbioqLCAqKnNlbGYtZWZmaWNhY3kqKiwgYW5kICoqdGVjaG5vbG9neSBpbnRlZ3JhdGlvbioqIGludGVyYWN0IHRvIGluZmx1ZW5jZSBsZWFybmVyc+KAmSBlbW90aW9uYWwgZXhwZXJpZW5jZXMgYW5kIGFjYWRlbWljIGVuZ2FnZW1lbnQuDQoNCiMjIyBEaXNjdXNzaW9uDQoNClRoZSBwcmVzZW50IHN0dWR5IGludmVzdGlnYXRlZCB0aGUgc3RydWN0dXJhbCByZWxhdGlvbnNoaXBzIGFtb25nIHRlY2hub2xvZ3kgdXNlLCBzZWxmLWVmZmljYWN5LCBpbnN0cnVjdGlvbmFsIGFwcHJvYWNoZXMsIGFuZCB0d28gZm9ybXMgb2YgYWNhZGVtaWMgYW54aWV0eeKAlGV2YWx1YXRpb24gYW54aWV0eSBhbmQgbGVhcm5pbmcgYW54aWV0eeKAlHdpdGhpbiBhIGNvbXByZWhlbnNpdmUgc3RydWN0dXJhbCBlcXVhdGlvbiBtb2RlbGluZyAoU0VNKSBmcmFtZXdvcmsuIFRoZSBmaW5kaW5ncyBwcm92aWRlIGltcG9ydGFudCBpbnNpZ2h0cyBpbnRvIGhvdyBpbmRpdmlkdWFsIGFuZCBpbnN0cnVjdGlvbmFsIGZhY3RvcnMgam9pbnRseSBzaGFwZSBsZWFybmVyc+KAmSBlbW90aW9uYWwgZXhwZXJpZW5jZXMgaW4gYWNhZGVtaWMgY29udGV4dHMuDQoNCkNvbnNpc3RlbnQgd2l0aCBwcmlvciByZXNlYXJjaCwgc2VsZi1lZmZpY2FjeSBlbWVyZ2VkIGFzIHRoZSBtb3N0IHJvYnVzdCBwcmVkaWN0b3Igb2YgYm90aCBldmFsdWF0aW9uIGFuZCBsZWFybmluZyBhbnhpZXR5LiBTdHVkZW50cyB3aG8gcmVwb3J0ZWQgaGlnaGVyIGNvbmZpZGVuY2UgaW4gdGhlaXIgYWNhZGVtaWMgYWJpbGl0aWVzIGV4cGVyaWVuY2VkIHNpZ25pZmljYW50bHkgbG93ZXIgbGV2ZWxzIG9mIGFueGlldHksIHVuZGVyc2NvcmluZyB0aGUgcHJvdGVjdGl2ZSBmdW5jdGlvbiBvZiBzZWxmLWJlbGllZiBpbiBjb3Bpbmcgd2l0aCBhY2FkZW1pYyBkZW1hbmRzLiBTaW1pbGFybHksIHRlY2hub2xvZ3kgdXNlIG5lZ2F0aXZlbHkgcHJlZGljdGVkIGJvdGggdHlwZXMgb2YgYW54aWV0eSwgc3VnZ2VzdGluZyB0aGF0IGZhbWlsaWFyaXR5IGFuZCBjb21mb3J0IHdpdGggdGVjaG5vbG9naWNhbCB0b29scyBtYXkgaGVscCBzdHVkZW50cyBuYXZpZ2F0ZSBsZWFybmluZyBlbnZpcm9ubWVudHMgbW9yZSBlZmZlY3RpdmVseSBhbmQgcmVkdWNlIGFwcHJlaGVuc2lvbiBhYm91dCBwZXJmb3JtYW5jZS4NCg0KQWx0aG91Z2ggc3R1ZGVudC1jZW50ZXJlZCBpbnN0cnVjdGlvbiB3YXMgb25seSBtYXJnaW5hbGx5IGFzc29jaWF0ZWQgd2l0aCByZWR1Y2VkIGxlYXJuaW5nIGFueGlldHksIHRoZSBkaXJlY3Rpb24gb2YgdGhpcyByZWxhdGlvbnNoaXAgaXMgdGhlb3JldGljYWxseSBtZWFuaW5nZnVsLiBMZWFybmVycyBleHBvc2VkIHRvIGluZHVjdGl2ZSwgY29vcGVyYXRpdmUsIGFuZCBpbnRlZ3JhdGl2ZSB0ZWFjaGluZyBzdHJhdGVnaWVzIG1heSBwZXJjZWl2ZSBncmVhdGVyIGF1dG9ub215IGFuZCBzdXBwb3J0LCB3aGljaCBjYW4gbGVzc2VuIGFueGlldHkgYW5kIGZvc3RlciBpbnRyaW5zaWMgbW90aXZhdGlvbi4gVGhlIHBvc2l0aXZlIGFzc29jaWF0aW9uIGJldHdlZW4gcmVzb3VyY2UgYXZhaWxhYmlsaXR5IGFuZCBsZWFybmluZyBhbnhpZXR5IHN1Z2dlc3RzIHRoYXQgYWNjZXNzIHRvIGFidW5kYW50IG1hdGVyaWFscyBkb2VzIG5vdCBuZWNlc3NhcmlseSBhbGxldmlhdGUgc3RyZXNzOyBpbnN0ZWFkLCBpdCBtYXkgaW50cm9kdWNlIGNvZ25pdGl2ZSBvdmVybG9hZCBvciBwZXJmb3JtYW5jZSBwcmVzc3VyZS4NCg0KR2VuZGVyIHNpZ25pZmljYW50bHkgcHJlZGljdGVkIGV2YWx1YXRpb24gYW54aWV0eSwgaGlnaGxpZ2h0aW5nIHRoZSBpbXBvcnRhbmNlIG9mIGNvbnNpZGVyaW5nIHNvY2lvY3VsdHVyYWwgYW5kIGRpc2NpcGxpbmFyeSBmYWN0b3JzIHRoYXQgc2hhcGUgaG93IGdlbmRlciBpbnRlcmFjdHMgd2l0aCBhY2FkZW1pYyBlbW90aW9ucy4gVGhlIHN0cm9uZyBwb3NpdGl2ZSBjb3ZhcmlhbmNlIGJldHdlZW4gZXZhbHVhdGlvbiBhbmQgbGVhcm5pbmcgYW54aWV0eSBpbmRpY2F0ZXMgdGhhdCB0aGVzZSBjb25zdHJ1Y3RzIGFyZSByZWxhdGVkIHlldCBkaXN0aW5jdCwgc3VwcG9ydGluZyB0aGVvcmllcyB0aGF0IGVtcGhhc2l6ZSBpbnRlcmNvbm5lY3RlZCBlbW90aW9uYWwgZXhwZXJpZW5jZXMgaW4gbGVhcm5pbmcuDQoNClRoZSBmaW5kaW5ncyB1bmRlcnNjb3JlIHRoZSBuZWVkIGZvciBpbnN0cnVjdGlvbmFsIGRlc2lnbnMgdGhhdCBlbmhhbmNlIHNlbGYtZWZmaWNhY3kgYW5kIHRlY2hub2xvZ2ljYWwgY29uZmlkZW5jZSBhcyBjZW50cmFsIHN0cmF0ZWdpZXMgZm9yIHJlZHVjaW5nIGFjYWRlbWljIGFueGlldHkuIEluc3RydWN0b3JzIGNhbiBwcm9tb3RlIHNlbGYtZWZmaWNhY3kgdGhyb3VnaCBzY2FmZm9sZGVkIGZlZWRiYWNrLCBtYXN0ZXJ5LW9yaWVudGVkIGFzc2Vzc21lbnRzLCBhbmQgb3Bwb3J0dW5pdGllcyBmb3Igc2VsZi1yZWZsZWN0aW9uLiBQdXJwb3NlZnVsIHRlY2hub2xvZ3kgaW50ZWdyYXRpb24gYW5kIHN0cnVjdHVyZWQgZ3VpZGFuY2UgY2FuIGZ1cnRoZXIgc3VwcG9ydCBjb25maWRlbmNlIGFuZCByZWR1Y2UgYW54aWV0eS4gRnV0dXJlIHN0dWRpZXMgc2hvdWxkIGV4cGxvcmUgYWRkaXRpb25hbCBwcmVkaWN0b3JzIGFuZCBjb250ZXh0dWFsIHZhcmlhYmxlcywgYXMgd2VsbCBhcyBlbXBsb3kgbG9uZ2l0dWRpbmFsIGRlc2lnbnMgdG8gY2xhcmlmeSBjYXVzYWwgcGF0aHdheXMuDQoNCkluIHN1bW1hcnksIHRoZSBmaW5kaW5ncyBkZW1vbnN0cmF0ZSB0aGF0IHNlbGYtZWZmaWNhY3kgYW5kIHRlY2hub2xvZ3kgdXNlIGFyZSBrZXkgcHJvdGVjdGl2ZSBmYWN0b3JzIGFnYWluc3QgYm90aCBldmFsdWF0aW9uIGFuZCBsZWFybmluZyBhbnhpZXR5LCB3aGVyZWFzIGluc3RydWN0aW9uYWwgY29udGV4dCBhbmQgcmVzb3VyY2UgbWFuYWdlbWVudCBwbGF5IHNlY29uZGFyeSByb2xlcy4gVGhlc2UgaW5zaWdodHMgY29udHJpYnV0ZSB0byBhIGdyb3dpbmcgdW5kZXJzdGFuZGluZyBvZiBob3cgcGVyc29uYWwgYW5kIHBlZGFnb2dpY2FsIGZhY3RvcnMgaW50ZXJhY3QgdG8gc2hhcGUgZW1vdGlvbmFsIGV4cGVyaWVuY2VzIGluIGxlYXJuaW5nIGVudmlyb25tZW50cy4NCg0KIyMjIFByYWN0aWNhbCBJbXBsaWNhdGlvbnMNCg0KMS4gRW5oYW5jZSBTdHVkZW50c+KAmSBTZWxmLUVmZmljYWN5OiBQcm92aWRlIG9wcG9ydHVuaXRpZXMgZm9yIGVhcmx5IHN1Y2Nlc3MsIG1hc3RlcnkgZXhwZXJpZW5jZXMsIGFuZCBwb3NpdGl2ZSBmZWVkYmFjayB0byBidWlsZCBsZWFybmVyc+KAmSBjb25maWRlbmNlLg0KMi4gUHJvbW90ZSBNZWFuaW5nZnVsIFRlY2hub2xvZ3kgSW50ZWdyYXRpb246IEludGVncmF0ZSBkaWdpdGFsIHRvb2xzIHB1cnBvc2VmdWxseSB3aXRoaW4gaW5zdHJ1Y3Rpb24gdG8gZm9zdGVyIGVuZ2FnZW1lbnQgYW5kIHJlZHVjZSB0ZWNobm9sb2d5LXJlbGF0ZWQgYW54aWV0eS4NCjMuIEFkb3B0IFN0dWRlbnQtQ2VudGVyZWQgVGVhY2hpbmcgUHJhY3RpY2VzOiBFbmNvdXJhZ2UgY29sbGFib3JhdGl2ZSwgcHJvYmxlbS1iYXNlZCwgYW5kIHBlZXItZHJpdmVuIGxlYXJuaW5nIHRvIGFsbGV2aWF0ZSBhbnhpZXR5IGFuZCBwcm9tb3RlIGF1dG9ub215Lg0KNC4gQmFsYW5jZSBSZXNvdXJjZSBQcm92aXNpb24gYW5kIENvZ25pdGl2ZSBMb2FkOiBDdXJhdGUgaW5zdHJ1Y3Rpb25hbCBtYXRlcmlhbHMgY2FyZWZ1bGx5IHRvIHByZXZlbnQgaW5mb3JtYXRpb24gb3ZlcmxvYWQgYW5kIGVuc3VyZSBjbGFyaXR5IG9mIGV4cGVjdGF0aW9ucy4NCjUuIEFkZHJlc3MgR2VuZGVyIGFuZCBDb250ZXh0dWFsIERpZmZlcmVuY2VzOiBUYWlsb3Igc3VwcG9ydCBzdHJhdGVnaWVzIHRvIGFkZHJlc3MgcG90ZW50aWFsIGdlbmRlci1iYXNlZCBhbmQgY29udGV4dHVhbCB2YXJpYXRpb25zIGluIGFjYWRlbWljIGFueGlldHkuDQoNCiMjIyBTdW1tYXJ5IG9mIEtleSBGaW5kaW5ncw0KDQpUaGlzIHN0dWR5IGVtcGxveWVkIHN0cnVjdHVyYWwgZXF1YXRpb24gbW9kZWxpbmcgdG8gZXhhbWluZSB0aGUgaW50ZXJwbGF5IGFtb25nIHRlY2hub2xvZ3kgdXNlLCBzZWxmLWVmZmljYWN5LCBpbnN0cnVjdGlvbmFsIGFwcHJvYWNoZXMsIGFuZCB0d28gZGltZW5zaW9ucyBvZiBhY2FkZW1pYyBhbnhpZXR5OiBldmFsdWF0aW9uIGFueGlldHkgYW5kIGxlYXJuaW5nIGFueGlldHkuIFRoZSBtb2RlbCBkZW1vbnN0cmF0ZWQgYW4gYWNjZXB0YWJsZSBvdmVyYWxsIGZpdCBhbmQgZXhwbGFpbmVkIGEgc3Vic3RhbnRpYWwgcHJvcG9ydGlvbiBvZiB2YXJpYW5jZSBpbiBib3RoIG91dGNvbWVzLg0KDQpUaGUgcmVzdWx0cyByZXZlYWxlZCB0aGF0IHNlbGYtZWZmaWNhY3kgYW5kIHRlY2hub2xvZ3kgdXNlIHdlcmUgdGhlIHN0cm9uZ2VzdCBwcm90ZWN0aXZlIGZhY3RvcnMgYWdhaW5zdCBhY2FkZW1pYyBhbnhpZXR5LiBTZWxmLWVmZmljYWN5IGhhZCB0aGUgbGFyZ2VzdCBuZWdhdGl2ZSBhc3NvY2lhdGlvbnMgd2l0aCBib3RoIGV2YWx1YXRpb24gYW5kIGxlYXJuaW5nIGFueGlldHksIGluZGljYXRpbmcgdGhhdCBzdHVkZW50cyB3aG8gZmVlbCBjb21wZXRlbnQgYXJlIGxlc3MgbGlrZWx5IHRvIGV4cGVyaWVuY2UgYW54aWV0eSBhY3Jvc3MgYWNhZGVtaWMgY29udGV4dHMuIFRlY2hub2xvZ3kgdXNlIHNpbWlsYXJseSByZWR1Y2VkIGFueGlldHksIHN1Z2dlc3RpbmcgdGhhdCBmYW1pbGlhcml0eSB3aXRoIGRpZ2l0YWwgdG9vbHMgZm9zdGVycyBjb21mb3J0IGFuZCBwZXJjZWl2ZWQgY29udHJvbCBkdXJpbmcgbGVhcm5pbmcgYW5kIGFzc2Vzc21lbnQuDQoNCldoaWxlIHN0dWRlbnQtY2VudGVyZWQgaW5zdHJ1Y3Rpb24gc2hvd2VkIGEgbWFyZ2luYWxseSBuZWdhdGl2ZSByZWxhdGlvbnNoaXAgd2l0aCBsZWFybmluZyBhbnhpZXR5LCByZXNvdXJjZSBhdmFpbGFiaWxpdHkgdW5leHBlY3RlZGx5IHByZWRpY3RlZCBoaWdoZXIgYW54aWV0eS4gR2VuZGVyIGRpZmZlcmVuY2VzIGFsc28gZW1lcmdlZCBmb3IgZXZhbHVhdGlvbiBhbnhpZXR5LCBzdWdnZXN0aW5nIHZhcmlhdGlvbiBpbiBlbW90aW9uYWwgcmVzcG9uc2VzIHRvIGFjYWRlbWljIGV2YWx1YXRpb24gYWNyb3NzIGdyb3Vwcy4NCg0KVG9nZXRoZXIsIHRoZXNlIGZpbmRpbmdzIGRlbW9uc3RyYXRlIHRoYXQgZm9zdGVyaW5nIHNlbGYtZWZmaWNhY3ksIGRpZ2l0YWwgY29tcGV0ZW5jZSwgYW5kIGJhbGFuY2VkIGluc3RydWN0aW9uYWwgZGVzaWduIGNhbiBzdWJzdGFudGlhbGx5IHJlZHVjZSBzdHVkZW50c+KAmSBhbnhpZXR5IGFuZCBwcm9tb3RlIG1vcmUgcG9zaXRpdmUgYWNhZGVtaWMgZXhwZXJpZW5jZXMuIFRoZSBzdHVkeSBjb250cmlidXRlcyB0byBhIGdyb3dpbmcgYm9keSBvZiBldmlkZW5jZSBoaWdobGlnaHRpbmcgdGhlIGludGVyY29ubmVjdGVkIHJvbGVzIG9mIHBlcnNvbmFsIGJlbGllZnMsIHRlY2hub2xvZ3ksIGFuZCBwZWRhZ29neSBpbiBzaGFwaW5nIHN0dWRlbnRz4oCZIGVtb3Rpb25hbCBlbmdhZ2VtZW50IGFuZCBzdWNjZXNzLg0KDQpcDQoNCiMgUmVmZXJlbmNlcw0KDQpCb3JpY2gsIEcuIEQuICgyMDE3KS4gRWZmZWN0aXZlIFRlYWNoaW5nIE1ldGhvZHM6IFJlc2VhcmNoLUJhc2VkIFByYWN0aWNlICg5dGggZWQuKS4gUGVhcnNvbi4gDQpCcm93biwgSC4gRC4sICYgTGVlLCBILiAoMTk5NCkuIFRlYWNoaW5nIGJ5IHByaW5jaXBsZXM6IEFuIGludGVyYWN0aXZlIGFwcHJvYWNoIHRvIGxhbmd1YWdlIHBlZGFnb2d5IChWb2wuIDEsIHAuIDk5NCkuIEVuZ2xld29vZCBDbGlmZnMsIE5KOiBQcmVudGljZSBIYWxsIFJlZ2VudHMuDQoNCkJydW5lciwgSi4gUy4gKDE5NjEpLiBUaGUgYWN0IG9mIGRpc2NvdmVyeS4gSGFydmFyZCBlZHVjYXRpb25hbCByZXZpZXcuDQpDYXR0ZWxsLCBSLiBCLiAoMTk1MikuIEZhY3RvciBhbmFseXNpczogYW4gaW50cm9kdWN0aW9uIGFuZCBtYW51YWwgZm9yIHRoZSBwc3ljaG9sb2dpc3QgYW5kIHNvY2lhbCBzY2llbnRpc3QuDQoNCkNoYW5nLCBILiwgJiBCZWlsb2NrLCBTLiBMLiAoMjAxNikuIFRoZSBtYXRoIGFueGlldHktbWF0aCBwZXJmb3JtYW5jZSBsaW5rIGFuZCBpdHMgcmVsYXRpb24gdG8gaW5kaXZpZHVhbCBhbmQgZW52aXJvbm1lbnRhbCBmYWN0b3JzOiBBIHJldmlldyBvZiBjdXJyZW50IGJlaGF2aW9yYWwgYW5kIHBzeWNob3BoeXNpb2xvZ2ljYWwgcmVzZWFyY2guIEN1cnJlbnQgT3BpbmlvbiBpbiBCZWhhdmlvcmFsIFNjaWVuY2VzLCAxMCwgMzPigJMzOC4NCg0KQ3JvbmJhY2gsIEwuIEouICgxOTUxKS4gQ29lZmZpY2llbnQgYWxwaGEgYW5kIHRoZSBpbnRlcm5hbCBzdHJ1Y3R1cmUgb2YgdGVzdHMuIEJpb21ldHJpa2EsIDE2LCAyOTfigJMzMzUuDQoNCkRha2VyLCBSLiBKLiwgR2F0dGFzLCBTLiBVLiwgU29rb2xvd3NraSwgSC4gTS4sIEdyZWVuLCBBLiBFLiwgJiBMeW9ucywgSS4gTS4gKDIwMjEpLiBGaXJzdC15ZWFyIHN0dWRlbnRz4oCZIG1hdGggYW54aWV0eSBwcmVkaWN0cyBTVEVNIGF2b2lkYW5jZSBhbmQgdW5kZXJwZXJmb3JtYW5jZSB0aHJvdWdob3V0IHVuaXZlcnNpdHksIGluZGVwZW5kZW50bHkgb2YgbWF0aCBhYmlsaXR5LiBOcGogU2NpZW5jZSBvZiBMZWFybmluZywgNigxKSwgMTcuDQoNCkRldmluZSwgQS4sIEZhd2NldHQsIEsuLCBTesWxY3MsIEQuLCAmIERvd2tlciwgQS4gKDIwMTIpLiBHZW5kZXIgZGlmZmVyZW5jZXMgaW4gbWF0aGVtYXRpY3MgYW54aWV0eSBhbmQgdGhlIHJlbGF0aW9uIHRvIG1hdGhlbWF0aWNzIHBlcmZvcm1hbmNlIHdoaWxlIGNvbnRyb2xsaW5nIGZvciB0ZXN0IGFueGlldHkuIEJlaGF2aW9yYWwgYW5kIGJyYWluIGZ1bmN0aW9ucywgOCgxKSwgMzMuDQoNCkRpU3RlZmFubywgQy4sIFpodSwgTS4sICYgTWluZHJpbGEsIEQuICgyMDA5KS4gVW5kZXJzdGFuZGluZyBhbmQgdXNpbmcgZmFjdG9yIHNjb3JlczogQ29uc2lkZXJhdGlvbnMgZm9yIHRoZSBhcHBsaWVkIHJlc2VhcmNoZXIuIFByYWN0aWNhbCBhc3Nlc3NtZW50LCByZXNlYXJjaCwgYW5kIGV2YWx1YXRpb24sIDE0KDEpLg0KDQpEcmVnZXIsIFIuIE0uLCAmIEFpa2VuIEpyLCBMLiBSLiAoMTk1NykuIFRoZSBpZGVudGlmaWNhdGlvbiBvZiBudW1iZXIgYW54aWV0eSBpbiBhIGNvbGxlZ2UgcG9wdWxhdGlvbi4gSm91cm5hbCBvZiBFZHVjYXRpb25hbCBQc3ljaG9sb2d5LCA0OCg2KSwgMzQ0Lg0KDQpEdW5jYW4sIE8uIEQuICgxOTYxKS4gQSBzb2Npb2Vjb25vbWljIGluZGV4IGZvciBhbGwgb2NjdXBhdGlvbnMuIE9jY3VwYXRpb25zIGFuZCBzb2NpYWwgc3RhdHVzLi4NCg0KRWxzZS1RdWVzdCwgTi4gTS4sIEh5ZGUsIEouIFMuLCAmIExpbm4sIE0uIEMuICgyMDEwKS4gQ3Jvc3MtbmF0aW9uYWwgcGF0dGVybnMgb2YgZ2VuZGVyIGRpZmZlcmVuY2VzIGluIG1hdGhlbWF0aWNzOiBhIG1ldGEtYW5hbHlzaXMuIFBzeWNob2xvZ2ljYWwgYnVsbGV0aW4sIDEzNigxKSwgMTAzLg0KDQpGb2dhcnR5LCBSLiAoMTk5MSkuIFRoZSBtaW5kZnVsIHNjaG9vbDogSG93IHRvIGludGVncmF0ZSB0aGUgY3VycmljdWxhLiBQYWxhdGluZSwgSUwuIFNreUxpZ2h0IFB1Ymxpc2hpbmcsIEluYy4gUmV0cmlldmVkIEZlYnJ1YXJ5LCAyMiwgMjAwMi4NCg0KR29ldHosIFQuLCBCaWVnLCBNLiwgTMO8ZHRrZSwgTy4sIFBla3J1biwgUi4sICYgSGFsbCwgTi4gQy4gKDIwMTMpLiBEbyBnaXJscyByZWFsbHkgZXhwZXJpZW5jZSBtb3JlIGFueGlldHkgaW4gbWF0aGVtYXRpY3M/LiBQc3ljaG9sb2dpY2FsIHNjaWVuY2UsIDI0KDEwKSwgMjA3OS0yMDg3Lg0KDQpHb3VnaCwgTWFyeSBPLiAoMTk1NCkuIFdoeSBmYWlsdXJlcyBpbiBtYXRoZW1hdGljcz8gTWF0aGVtYXBob2JpYTogQ2F1c2VzIGFuZCB0cmVhdG1lbnRzLiBUaGUgQ2xlYXJpbmcgSG91c2U6IEEgSm91cm5hbCBvZiBFZHVjYXRpb25hbCBTdHJhdGVnaWVzLCBJc3N1ZXMgYW5kIElkZWFzLCAyOCg1KSwgMjkw4oCTMjk0LiANCg0KR3V0dG1hbiwgTC4gKDE5NTQpLiBTb21lIG5lY2Vzc2FyeSBjb25kaXRpb25zIGZvciBjb21tb24tZmFjdG9yIGFuYWx5c2lzLiBQc3ljaG9tZXRyaWthLCAxOSgyKSwgMTQ5LTE2MS4NCg0KSGVtYnJlZSwgUi4gKDE5OTApLiBUaGUgbmF0dXJlLCBlZmZlY3RzLCBhbmQgcmVsaWVmIG9mIG1hdGhlbWF0aWNzIGFueGlldHkuIEpvdXJuYWwgZm9yIHJlc2VhcmNoIGluIG1hdGhlbWF0aWNzIGVkdWNhdGlvbiwgMjEoMSksIDMzLTQ2Lg0KDQpIb3BrbywgRC4gUi4sIE1haGFkZXZhbiwgUi4sIEJhcmUsIFIuIEwuLCAmIEh1bnQsIE0uIEsuICgyMDAzKS4gVGhlIGFiYnJldmlhdGVkIG1hdGggYW54aWV0eSBzY2FsZSAoQU1BUykgY29uc3RydWN0aW9uLCB2YWxpZGl0eSwgYW5kIHJlbGlhYmlsaXR5LiBBc3Nlc3NtZW50LCAxMCgyKSwgMTc44oCTMTgyLg0KDQogSGlyc2NoYmVyZywgRS4sICYgU3RhbmRpc2gsIEMuIFYuICgxOTU5KS4gQSBtZXRob2Qgb2YgZGVyaXZpbmcgYSBzdHJhdGlmaWNhdGlvbiBzY29yZSBieSB1c2luZyB0aGUgcHJpbmNpcGFsIGNvbXBvbmVudHMgb2YgdGhlIGNvcnJlbGF0aW9uIG1hdHJpeC4gQW1lcmljYW4gU3RhdGlzdGljYWwgQXNzb2NpYXRpb24sIFByb2NlZWRpbmdzIG9mIHRoZSBTb2NpYWwgU3RhdGlzdGljcyBTZWN0aW9uLCAxOTU5LCAyMjAtMjI1Lg0KDQpKYWNvYnMsIEguIEguICgxOTg5KS4gSW50ZXJkaXNjaXBsaW5hcnkgY3VycmljdWx1bTogRGVzaWduIGFuZCBpbXBsZW1lbnRhdGlvbi4gQXNzb2NpYXRpb24gZm9yIFN1cGVydmlzaW9uIGFuZCBDdXJyaWN1bHVtIERldmVsb3BtZW50LCAxMjUwIE4uIFBpdHQgU3RyZWV0LCBBbGV4YW5kcmlhLCBWQSAyMjMxNC4NCg0KSm9sbGlmZmUsIEkuIFQuLCAmIENhZGltYSwgSi4gKDIwMTYpLiBQcmluY2lwYWwgQ29tcG9uZW50IEFuYWx5c2lzOiBBIFJldmlldyBhbmQgUmVjZW50IERldmVsb3BtZW50cy4gUGhpbG9zb3BoaWNhbCBUcmFuc2FjdGlvbnMgb2YgdGhlIFJveWFsIFNvY2lldHkgQSwgMzc0KDIwNjUpLCAyMDE1MDIwMi4NCg0KSm9obnNvbiwgRC4gVy4sIEpvaG5zb24sIFIuIFQuLCAmIFNtaXRoLCBLLiBBLiAoMjAxNCkuIENvb3BlcmF0aXZlIGxlYXJuaW5nOiBJbXByb3ZpbmcgdW5pdmVyc2l0eSBpbnN0cnVjdGlvbiBieSBiYXNpbmcgcHJhY3RpY2Ugb24gdmFsaWRhdGVkIHRoZW9yeS4gSm91cm5hbCBvbiBleGNlbGxlbmNlIGluIGNvbGxlZ2UgdGVhY2hpbmcsIDI1KDMmNCkuDQoNCkpvc2UgTS4gQ2FyZGlubyBKci4gYW5kIFJ1dGggQS4gT3J0ZWdhLURlbGEgQ3J1eiwgVW5kZXJzdGFuZGluZyBvZiBsZWFybmluZyBzdHlsZXMgYW5kIHRlYWNoaW5nIHN0cmF0ZWdpZXMgdG93YXJkcyBpbXByb3ZpbmcgdGhlIHRlYWNoaW5nIGFuZCBsZWFybmluZyBvZiBtYXRoZW1hdGljcywgTFVNQVQgR2VuZXJhbCBJc3N1ZSwgIFZvbCA4IE5vIDEgKDIwMjApLCAxOeKAkzQzLiBEb2k6IDEwLjMxMTI5LyBMVU1BVC44LjEuMTM0OA0KDQpKb3ljZSwgQi4sIFdlaWwsIE0uLCAmIENhbGhvdW4sIEUuICgyMDE1KS4gTW9kZWxzIG9mIFRlYWNoaW5nICg5dGggZWQuKS4gUGVhcnNvbi4NCg0KS2xlZSwgSC4gTC4sIEJ1ZWhsLCBNLiBNLiwgJiBNaWxsZXIsIEEuIEQuICgyMDIyKS4gU3RyYXRlZ2llcyBmb3IgYWxsZXZpYXRpbmcgc3R1ZGVudHPigJkgbWF0aCBhbnhpZXR5OiBDb250cm9sLXZhbHVlIHRoZW9yeSBpbiBwcmFjdGljZS4gVGhlb3J5IEludG8gUHJhY3RpY2UsIDYxKDEpLCA0OeKAkzYxLg0KDQpMYXphcnNmZWxkLCBQLiBGLiwgU3RvdWZmZXIsIFMuIEEuLCBHdXR0bWFuLCBMLiwgJiBTdWNobWFuLCBFLiBBLiAoMTk1MCkuIE1lYXN1cmVtZW50IGFuZCBwcmVkaWN0aW9uLiBTQSBTdG91ZmZlciAow6lkLikgU3R1ZGllcyBpbiBzb2NpYWwgcHN5Y2hvbG9neSBpbiB3b3JsZCB3YXIgSUksIDQuDQoNCkzDs3Blei1Cb25pbGxhLCBKLiBNLmwgYW5kIEzDs3Blei1Cb25pbGxhLCBMLiBNLiAoMjAxMiksIFZhbGlkYXRpb24gb2YgYW4gaW5mb3JtYXRpb24gdGVjaG5vbG9neSBhbnhpZXR5IHNjYWxlIGluIHVuZGVyZ3JhZHVhdGVzLCBCcml0aXNoIEpvdXJuYWwgb2YgRWR1Y2F0aW9uYWwgVGVjaG5vbG9neSBWb2wgNDMuIE5vIDIuICBFNTbigJNFNTguICBkb2k6MTAuMTExMS9qLjE0NjctODUzNS4yMDExLjAxMjU2LngNCg0KTWFyc2gsIEguIFcuICgxOTk2KS4gUG9zaXRpdmUgYW5kIG5lZ2F0aXZlIHNlbGYtZXN0ZWVtOiBBIHN1YnN0YW50aXZlbHkgbWVhbmluZ2Z1bCBkaXN0aW5jdGlvbiBvciBhcnRpZmFjdG9ycz8gSm91cm5hbCBvZiBQZXJzb25hbGl0eSBhbmQgU29jaWFsIFBzeWNob2xvZ3ksIDcwKDQpLCA4MTDigJM4MTkuDQoNCk1jRG9uYWxkLCBSLiBQLiAoMTk5OSkuIFRlc3QgdGhlb3J5OiBBIHVuaWZpZWQgdHJlYXRtZW50LiBNYWh3YWg6IEVybGJhdW0uDQoNCk1vbGluZXIsIEwuLCAmIEFsZWdyZSwgRi4gKDIwMjApLiBQZWVyIHR1dG9yaW5nIGVmZmVjdHMgb24gc3R1ZGVudHPigJkgbWF0aGVtYXRpY3MgYW54aWV0eTogQSBtaWRkbGUgc2Nob29sIGV4cGVyaWVuY2UuIEZyb250aWVycyBpbiBQc3ljaG9sb2d5LCAxMSwgMTYxMC4NCg0KT+KAmUxlYXJ5LCBLLiwgRml0enBhdHJpY2ssIEMuIEwuLCAmIEhhbGxldHQsIEQuICgyMDE3KS4gTWF0aCBhbnhpZXR5IGlzIHJlbGF0ZWQgdG8gc29tZSwgYnV0IG5vdCBhbGwsIGV4cGVyaWVuY2VzIHdpdGggbWF0aC4gRnJvbnRpZXJzIGluIFBzeWNob2xvZ3ksIDgsIDIwNjcuDQoNCk9ybXJvZCwgSi4gRS4gKDIwMjApLiBIdW1hbiBMZWFybmluZyAoOHRoIGVkLikuIFBlYXJzb24NCg0KUGxldHplciwgQi4sIFdvb2QsIEcuLCBTY2hlcm5kbCwgVC4sIEtlcnNjaGJhdW0sIEguIEguLCAmIE51ZXJrLCBILkMuICgyMDE2KS4gQ29tcG9uZW50cyBvZiBtYXRoZW1hdGljcyBhbnhpZXR5OiBGYWN0b3IgbW9kZWxpbmcgb2YgdGhlIE1BUlMzMC1icmllZi4gRnJvbnRpZXJzIGluIFBzeWNob2xvZ3ksIDcsIDkxLg0KDQpQcmluY2UsIE0uIEouLCAmIEZlbGRlciwgUi4gTS4gKDIwMDYpLiBJbmR1Y3RpdmUgdGVhY2hpbmcgYW5kIGxlYXJuaW5nIG1ldGhvZHM6IERlZmluaXRpb25zLCBjb21wYXJpc29ucywgYW5kIHJlc2VhcmNoIGJhc2VzLiBKb3VybmFsIG9mIGVuZ2luZWVyaW5nIGVkdWNhdGlvbiwgOTUoMiksIDEyMy0xMzguDQoNClJpY2hhcmRzb24sIEYuIEMuLCAmIFN1aW5uLCBSLiBNLiAoMTk3MikuIFRoZSBtYXRoZW1hdGljcyBhbnhpZXR5IHJhdGluZyBzY2FsZTogUHN5Y2hvbWV0cmljIGRhdGEuIEpvdXJuYWwgb2YgQ291bnNlbGluZyBQc3ljaG9sb2d5LCAxOSg2KSwgNTUxLg0KDQpSb3pnb25qdWssIEQuLCBLcmFhdiwgVC4sIE1pa2tvciwgSy4sIE9yYXYtUHV1cmFuZCwgSy4sICYgVMOkaHQsIEsuICgyMDIwKS4gTWF0aGVtYXRpY3MgYW54aWV0eSBhbW9uZyBTVEVNIGFuZCBzb2NpYWwgc2NpZW5jZSBzdHVkZW50czogVGhlIHJvbGVzIG9mIG1hdGhlbWF0aWNzIHNlbGYtZWZmaWNhY3ksIGFuZCBkZWVwIGFuZCBzdXJmYWNlIGFwcHJvYWNoIHRvIGxlYXJuaW5nLiBJbnRlcm5hdGlvbmFsIEpvdXJuYWwgb2YgU1RFTSBFZHVjYXRpb24sIDcoMSksIDHigJMxMS4NCg0KU2Vnb29sLCBOLiBLLiwgQ2FybHNvbiwgSi4gUy4sIEdvZm9ydGgsIEEuIE4uLCBWb24gRGVyIEVtYnNlLCBOLiwgJiBCYXJ0ZXJpYW4sIEouIEEuICgyMDEzKS4gSGVpZ2h0ZW5lZCB0ZXN0IGFueGlldHkgYW1vbmcgeW91bmcgY2hpbGRyZW46IEVsZW1lbnRhcnkgc2Nob29sIHN0dWRlbnRz4oCZIGFueGlvdXMgcmVzcG9uc2VzIHRvIGhpZ2gtc3Rha2VzIHRlc3RpbmcuIFBzeWNob2xvZ3kgaW4gdGhlIFNjaG9vbHMsIDUwKDUpLCA0ODnigJM0OTkuDQoNCldhdHNvbiwgRC4sIENsYXJrLCBMLiBBLiwgJiBUZWxsZWdlbiwgQS4gKDE5ODgpLiBEZXZlbG9wbWVudCBhbmQgdmFsaWRhdGlvbiBvZiBicmllZiBtZWFzdXJlcyBvZiBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgYWZmZWN0OiBUaGUgUEFOQVMgc2NhbGVzLiBKb3VybmFsIG9mIFBlcnNvbmFsaXR5IGFuZCBTb2NpYWwgUHN5Y2hvbG9neSwgNTQoNiksIDEwNjPigJMxMDcwLg0KDQpXaWxzb24sIFMuICgyMDEzKS4gTWF0dXJlIGFnZSBwcmUtc2VydmljZSB0ZWFjaGVyc+KAmSBtYXRoZW1hdGljcyBhbnhpZXR5IGFuZCBmYWN0b3JzIGltcGFjdGluZyBvbiB1bml2ZXJzaXR5IHJldGVudGlvbi4gTWF0aGVtYXRpY3MgRWR1Y2F0aW9uOiBZZXN0ZXJkYXksIFRvZGF5IGFuZCBUb21vcnJvdyAoTUVSR0EzNiksIDY2NuKAkzY3My4NCg0KDQoNClwNCg0KIyBBcHBlbmRpY2VzDQoNCiMjIE1hdGhlbWF0aWNzIG9mIFBDQQ0KDQoNCioqMS4gUHJvYmxlbSBEZWZpbml0aW9uKioNCg0KV2Ugd2lsbCB1c2UgYSBxdWVzdGlvbm5haXJlIHdpdGggZm91ciBpdGVtcyB0aGF0IGFzc2VzcyBtYXRoIGV2YWx1YXRpb24gYW54aWV0eSB0byBkZW1vbnN0cmF0ZSB0aGUgcHJvY2VkdXJlLg0KDQoqICR4XzEkOiBUaGlua2luZyBhYm91dCBhIG1hdGggdGVzdCB0aGUgZGF5IGJlZm9yZSB5b3UgdGFrZSBpdC4NCiogJHhfMiQ6IFRha2luZyBhIG1hdGggdGVzdC4NCiogJHhfMyQ6IEJlaW5nIGdpdmVuIGEgaG9tZXdvcmsgYXNzaWdubWVudCBvZiBtYW55IGRpZmZpY3VsdCBwcm9ibGVtcyB0aGF0IGlzIGR1ZSBmb3IgdGhlIG5leHQgY2xhc3MgbWVldGluZy4NCiogJHhfNCQ6IEJlaW5nIGdpdmVuIGEgcXVpeiBvbiBtYXRoIHdpdGhvdXQga25vd2luZyBpbiBhZHZhbmNlLg0KDQoNCkxldCAkXG1hdGhiZnt4fSA9IFt4XzEsIHhfMiwgeF8zLCB4XzRdXlQkIGJlIGEgcmFuZG9tIHZlY3RvciByZXByZXNlbnRpbmcgdGhlIHJlc3BvbnNlcyBvZiBhIHJhbmRvbWx5IHNlbGVjdGVkIGluZGl2aWR1YWwgdG8gdGhlIGZvdXIgaXRlbXMuIFdlIGFzc3VtZSAkXG1hdGhiZnt4fSQgaGFzIGEgcG9wdWxhdGlvbiBtZWFuIHZlY3RvciAkXGJvbGRzeW1ib2x7XG11fSQgYW5kIHBvcHVsYXRpb24gY292YXJpYW5jZSBtYXRyaXggJFxib2xkc3ltYm9se1xTaWdtYX0kLg0KDQpXZSBjb2xsZWN0IGEgc2FtcGxlIG9mICRuJCBpbmRpdmlkdWFscy4gVGhlIGRhdGEgbWF0cml4IGlzICRcbWF0aGJme1h9X3tuIFx0aW1lcyA0fSQsIHdoZXJlIGVhY2ggcm93IGlzIGFuIGluZGl2aWR1YWwncyByZXNwb25zZSB2ZWN0b3IuIFRoZSBzYW1wbGUgbWVhbiB2ZWN0b3IgaXMgJFxiYXJ7XG1hdGhiZnt4fX0kLCBhbmQgdGhlIHNhbXBsZSBjb3ZhcmlhbmNlIG1hdHJpeCBpcyAkXG1hdGhiZntTfSQuDQoNCioqMi4gUHJlcHJvY2Vzc2luZzogQ2VudGVyaW5nIHRoZSBEYXRhKioNCg0KVGhlIGZpcnN0IHN0ZXAgaXMgdG8gY2VudGVyIHRoZSBkYXRhLiBXZSBzdWJ0cmFjdCB0aGUgbWVhbiBvZiBlYWNoIHZhcmlhYmxlLCBjcmVhdGluZyBhIG5ldyBkYXRhIG1hdHJpeCAkXG1hdGhiZntZfSQ6DQoNCiQkDQpcbWF0aGJme1l9ID0gXG1hdGhiZntYfSAtIFxtYXRoYmZ7MX1cYmFye1xtYXRoYmZ7eH19XlQNCiQkDQoNCndoZXJlICRcbWF0aGJmezF9JCBpcyBhbiAkbiBcdGltZXMgMSQgdmVjdG9yIG9mIG9uZXMuIFRoZSBlbGVtZW50cyBvZiAkXG1hdGhiZntZfSQgYXJlICR5X3tpan0gPSB4X3tpan0gLSBcYmFye3h9X2okLiBGcm9tIHRoaXMgcG9pbnQgZm9yd2FyZCwgd2Ugd29yayB3aXRoIHRoZSBjZW50ZXJlZCBkYXRhICRcbWF0aGJme1l9JCwgZW5zdXJpbmcgJEVbXG1hdGhiZnt5fV0gPSBcbWF0aGJmezB9JC4NCg0KKiozLiBHb2FsIG9mIFByaW5jaXBhbCBDb21wb25lbnQgQW5hbHlzaXMgKFBDQSkqKg0KDQpUaGUgZ29hbCBvZiBQQ0EgaXMgdG8gZmluZCBhIG5ldyBzZXQgb2YgdW5jb3JyZWxhdGVkIHZhcmlhYmxlcyAkXG1hdGhiZnt6fSA9IFt6XzEsIHpfMiwgel8zLCB6XzRdXlQkLCBjYWxsZWQgdGhlIFx0ZXh0YmZ7UHJpbmNpcGFsIENvbXBvbmVudHN9IChQQ3MpLCB3aGljaCBhcmUgbGluZWFyIGNvbWJpbmF0aW9ucyBvZiB0aGUgb3JpZ2luYWwgY2VudGVyZWQgdmFyaWFibGVzICRcbWF0aGJme3l9JC4NCg0KJCQNClxtYXRoYmZ7en0gPSBcbWF0aGJme1d9XlRcbWF0aGJme3l9DQokJA0KDQpUaGUgbWF0cml4ICRcbWF0aGJme1d9JCBpcyBhbiBvcnRob2dvbmFsIG1hdHJpeCAoJFxtYXRoYmZ7V31eVFxtYXRoYmZ7V30gPSBcbWF0aGJme0l9JCkgd2hvc2UgY29sdW1ucyAkXG1hdGhiZnt3fV9pJCBhcmUgdGhlIFx0ZXh0YmZ7bG9hZGluZyB2ZWN0b3JzfS4gVGhlIGNvbXBvbmVudHMgbXVzdCBzYXRpc2Z5Og0KDQoqIFRoZSBmaXJzdCBjb21wb25lbnQsICR6XzEgPSBcbWF0aGJme3d9XzFeVCBcbWF0aGJme3l9JCwgaGFzIHRoZSBtYXhpbXVtIHBvc3NpYmxlIHZhcmlhbmNlLg0KKiBUaGUgJGskLXRoIGNvbXBvbmVudCwgJHpfayA9IFxtYXRoYmZ7d31fa15UIFxtYXRoYmZ7eX0kLCBoYXMgdGhlIG1heGltdW0gcG9zc2libGUgdmFyaWFuY2Ugc3ViamVjdCB0byBiZWluZyB1bmNvcnJlbGF0ZWQgd2l0aCAob3J0aG9nb25hbCB0bykgYWxsIHByZXZpb3VzIGNvbXBvbmVudHMgJHpfMSwgXGRvdHMsIHpfe2stMX0kLg0KIA0KDQoqKjQuIERlcml2YXRpb24gb2YgdGhlIEZpcnN0IFByaW5jaXBhbCBDb21wb25lbnQqKg0KDQpMZXQgJFxtYXRoYmZ7d31fMSQgYmUgdGhlIHZlY3RvciBvZiB3ZWlnaHRzIGZvciB0aGUgZmlyc3QgUEMsICR6XzEgPSBcbWF0aGJme3d9XzFeVCBcbWF0aGJme3l9JC4NClRoZSBzYW1wbGUgdmFyaWFuY2Ugb2YgJHpfMSQgaXMgZ2l2ZW4gYnk6DQoNCiQkDQpcYmVnaW57YWxpZ24qfQ0KXHRleHR7VmFyfSh6XzEpICY9IFx0ZXh0e1Zhcn0oXG1hdGhiZnt3fV8xXlQgXG1hdGhiZnt5fSkgXFwNCiAgICAgICAgICAgICAgICAmPSBFWyhcbWF0aGJme3d9XzFeVCBcbWF0aGJme3l9KShcbWF0aGJme3d9XzFeVCBcbWF0aGJme3l9KV5UXSBccXVhZCBcdGV4dHsoc2luY2V9IEVbXG1hdGhiZnt5fV09XG1hdGhiZnswfSkgXFwNCiAgICAgICAgICAgICAgICAmPSBFW1xtYXRoYmZ7d31fMV5UIFxtYXRoYmZ7eX0gXG1hdGhiZnt5fV5UIFxtYXRoYmZ7d31fMV0gXFwNCiAgICAgICAgICAgICAgICAmPSBcbWF0aGJme3d9XzFeVCBFW1xtYXRoYmZ7eX0gXG1hdGhiZnt5fV5UXSBcbWF0aGJme3d9XzEgXFwNCiAgICAgICAgICAgICAgICAmPSBcbWF0aGJme3d9XzFeVCBcYm9sZHN5bWJvbHtcU2lnbWF9IFxtYXRoYmZ7d31fMQ0KXGVuZHthbGlnbip9DQokJA0KDQoNCkluIHByYWN0aWNlLCB3ZSB1c2UgdGhlIHNhbXBsZSBjb3ZhcmlhbmNlIG1hdHJpeCAkXG1hdGhiZntTfSA9IFxmcmFjezF9e24tMX0gXG1hdGhiZntZfV5UIFxtYXRoYmZ7WX0kLg0KDQpXZSB3aXNoIHRvIG1heGltaXplICRcbWF0aGJme3d9XzFeVCBcbWF0aGJme1N9IFxtYXRoYmZ7d31fMSQgc3ViamVjdCB0byB0aGUgbm9ybWFsaXphdGlvbiBjb25zdHJhaW50ICRcbWF0aGJme3d9XzFeVCBcbWF0aGJme3d9XzEgPSAxJCAodG8gcHJldmVudCB0aGUgdmFyaWFuY2UgZnJvbSBncm93aW5nIGFyYml0cmFyaWx5IGxhcmdlKS4gV2Ugc29sdmUgdGhpcyB1c2luZyB0aGUgbWV0aG9kIG9mIExhZ3JhbmdlIG11bHRpcGxpZXJzLg0KDQpUaGUgTGFncmFuZ2lhbiBpczoNCg0KJCQNClxtYXRoY2Fse0x9KFxtYXRoYmZ7d31fMSwgXGxhbWJkYV8xKSA9IFxtYXRoYmZ7d31fMV5UIFxtYXRoYmZ7U30gXG1hdGhiZnt3fV8xIC0gXGxhbWJkYV8xIChcbWF0aGJme3d9XzFeVCBcbWF0aGJme3d9XzEgLSAxKQ0KJCQNCg0KVGFraW5nIHRoZSBncmFkaWVudCB3aXRoIHJlc3BlY3QgdG8gJFxtYXRoYmZ7d31fMSQgYW5kIHNldHRpbmcgaXQgdG8gemVybzoNCg0KJCQNClxmcmFje1xwYXJ0aWFsIFxtYXRoY2Fse0x9fXtccGFydGlhbCBcbWF0aGJme3d9XzF9ID0gMlxtYXRoYmZ7U31cbWF0aGJme3d9XzEgLSAyXGxhbWJkYV8xIFxtYXRoYmZ7d31fMSA9IDANCiQkDQoNCg0KVGhpcyB5aWVsZHMgdGhlIGtleSBcdGV4dGJme2VpZ2VudmFsdWUgZXF1YXRpb259Og0KDQokJA0KXGJlZ2lue2VxdWF0aW9ufQ0KXG1hdGhiZntTfSBcbWF0aGJme3d9XzEgPSBcbGFtYmRhXzEgXG1hdGhiZnt3fV8xDQpcZW5ke2VxdWF0aW9ufQ0KJCQNCg0KU3Vic3RpdHV0aW5nIHRoZSBhYm92ZSBlcXVhdGlvbiBiYWNrIGludG8gdGhlIHZhcmlhbmNlIGV4cHJlc3Npb246DQoNCiQkDQpcdGV4dHtWYXJ9KHpfMSkgPSBcbWF0aGJme3d9XzFeVCBcbWF0aGJme1N9IFxtYXRoYmZ7d31fMSA9IFxtYXRoYmZ7d31fMV5UIChcbGFtYmRhXzEgXG1hdGhiZnt3fV8xKSA9IFxsYW1iZGFfMSBcbWF0aGJme3d9XzFeVCBcbWF0aGJme3d9XzEgPSBcbGFtYmRhXzENCiQkDQoNClRodXMsIHRoZSB2YXJpYW5jZSBvZiB0aGUgZmlyc3QgcHJpbmNpcGFsIGNvbXBvbmVudCAkel8xJCBpcyB0aGUgZWlnZW52YWx1ZSAkXGxhbWJkYV8xJC4gVG8gbWF4aW1pemUgdGhlIHZhcmlhbmNlLCB3ZSBtdXN0IGNob29zZSB0aGUgXHRleHRiZntlaWdlbnZlY3RvciAkXG1hdGhiZnt3fV8xJCBjb3JyZXNwb25kaW5nIHRvIHRoZSBsYXJnZXN0IGVpZ2VudmFsdWUgb2YgJFxtYXRoYmZ7U30kfS4NCg0KKio1LiBEZXJpdmF0aW9uIG9mIHRoZSBTZWNvbmQgUHJpbmNpcGFsIENvbXBvbmVudCoqDQoNCldlIG5vdyBzZWVrIHRoZSBzZWNvbmQgY29tcG9uZW50ICR6XzIgPSBcbWF0aGJme3d9XzJeVCBcbWF0aGJme3l9JCB0aGF0IGhhcyBtYXhpbXVtIHZhcmlhbmNlLCBzdWJqZWN0IHRvICRcbWF0aGJme3d9XzJeVCBcbWF0aGJme3d9XzIgPSAxJCBhbmQgJFxtYXRoYmZ7d31fMl5UIFxtYXRoYmZ7d31fMSA9IDAkIChlbnN1cmluZyAkel8yJCBpcyB1bmNvcnJlbGF0ZWQgd2l0aCAkel8xJCkuDQoNClRoZSBMYWdyYW5naWFuIGZvciB0aGlzIHByb2JsZW0gaXM6DQoNCiQkDQpcbWF0aGNhbHtMfShcbWF0aGJme3d9XzIsIFxsYW1iZGFfMiwgXHBoaSkgPSBcbWF0aGJme3d9XzJeVCBcbWF0aGJme1N9IFxtYXRoYmZ7d31fMiAtIFxsYW1iZGFfMiAoXG1hdGhiZnt3fV8yXlQgXG1hdGhiZnt3fV8yIC0gMSkgLSBccGhpIChcbWF0aGJme3d9XzJeVCBcbWF0aGJme3d9XzEpDQokJA0KDQpUYWtpbmcgdGhlIGdyYWRpZW50IHdpdGggcmVzcGVjdCB0byAkXG1hdGhiZnt3fV8yJCBhbmQgc2V0dGluZyBpdCB0byB6ZXJvOg0KDQokJA0KXGZyYWN7XHBhcnRpYWwgXG1hdGhjYWx7TH19e1xwYXJ0aWFsIFxtYXRoYmZ7d31fMn0gPSAyXG1hdGhiZntTfVxtYXRoYmZ7d31fMiAtIDJcbGFtYmRhXzIgXG1hdGhiZnt3fV8yIC0gXHBoaSBcbWF0aGJme3d9XzEgPSAwDQokJA0KDQpNdWx0aXBseSB0aGlzIGVxdWF0aW9uIG9uIHRoZSBsZWZ0IGJ5ICRcbWF0aGJme3d9XzFeVCQ6DQoNCiQkDQoyXG1hdGhiZnt3fV8xXlRcbWF0aGJme1N9XG1hdGhiZnt3fV8yIC0gMlxsYW1iZGFfMiBcbWF0aGJme3d9XzFeVFxtYXRoYmZ7d31fMiAtIFxwaGkgXG1hdGhiZnt3fV8xXlRcbWF0aGJme3d9XzEgPSAwDQokJA0KDQpGcm9tIHRoZSBlaWdlbnZhbHVlIGVxdWF0aW9uIGZvciAkXG1hdGhiZnt3fV8xJCwgd2Uga25vdyAkXG1hdGhiZnt3fV8xXlRcbWF0aGJme1N9ID0gXGxhbWJkYV8xIFxtYXRoYmZ7d31fMV5UJC4gVGhlIG9ydGhvZ29uYWxpdHkgY29uc3RyYWludCBnaXZlcyAkXG1hdGhiZnt3fV8xXlRcbWF0aGJme3d9XzI9MCQuIFN1YnN0aXR1dGluZyB0aGVzZToNCg0KJCQNCjJcbGFtYmRhXzEgXG1hdGhiZnt3fV8xXlRcbWF0aGJme3d9XzIgLSAwIC0gXHBoaSAoMSkgPSAwIFxpbXBsaWVzIDJcbGFtYmRhXzEgKDApIC0gXHBoaSA9IDAgXGltcGxpZXMgXHBoaSA9IDANCiQkDQoNCg0KV2l0aCAkXHBoaT0wJCwgdGhlIGdyYWRpZW50IGVxdWF0aW9uIHNpbXBsaWZpZXMgdG86DQoNCiQkDQoyXG1hdGhiZntTfVxtYXRoYmZ7d31fMiAtIDJcbGFtYmRhXzIgXG1hdGhiZnt3fV8yID0gMCBcaW1wbGllcyBcbWF0aGJme1N9IFxtYXRoYmZ7d31fMiA9IFxsYW1iZGFfMiBcbWF0aGJme3d9XzINCiQkDQoNClRoaXMgaXMgYWdhaW4gYW4gZWlnZW52YWx1ZSBlcXVhdGlvbi4gVGhlIHZhcmlhbmNlIG9mICR6XzIkIGlzICRcbGFtYmRhXzIkLiBUbyBtYXhpbWl6ZSB0aGUgdmFyaWFuY2UsIHdlIGNob29zZSB0aGUgZWlnZW52ZWN0b3IgJFxtYXRoYmZ7d31fMiQgY29ycmVzcG9uZGluZyB0byB0aGUgXHRleHRiZntzZWNvbmQgbGFyZ2VzdCBlaWdlbnZhbHVlfSAkXGxhbWJkYV8yJC4gVGhlIG9ydGhvZ29uYWxpdHkgJFxtYXRoYmZ7d31fMl5UIFxtYXRoYmZ7d31fMSA9IDAkIGlzIGF1dG9tYXRpY2FsbHkgc2F0aXNmaWVkIGZvciBkaXN0aW5jdCBlaWdlbnZhbHVlcyBzaW5jZSAkXG1hdGhiZntTfSQgaXMgc3ltbWV0cmljLg0KDQoqKjYuIFN1YnNlcXVlbnQgQ29tcG9uZW50cyBhbmQgRnVsbCBTb2x1dGlvbioqDQoNClRoaXMgcHJvY2VzcyBjb250aW51ZXMgZm9yIGFsbCBmb3VyIGNvbXBvbmVudHMuIFRoZSBzb2x1dGlvbiB0byB0aGUgUENBIHByb2JsZW0gaXMgZm91bmQgYnkgcGVyZm9ybWluZyB0aGUgXHRleHRiZntlaWdlbmRlY29tcG9zaXRpb259IG9mIHRoZSBzYW1wbGUgY292YXJpYW5jZSBtYXRyaXggJFxtYXRoYmZ7U30kOg0KDQokJA0KXG1hdGhiZntTfSA9IFxtYXRoYmZ7V30gXGJvbGRzeW1ib2x7XExhbWJkYX0gXG1hdGhiZntXfV5UDQokJA0KDQp3aGVyZToNCg0KKiAgJFxib2xkc3ltYm9se1xMYW1iZGF9JCBpcyBhIGRpYWdvbmFsIG1hdHJpeCBjb250YWluaW5nIHRoZSBlaWdlbnZhbHVlcyBpbiBkZXNjZW5kaW5nIG9yZGVyOiAkXGxhbWJkYV8xIFxnZSBcbGFtYmRhXzIgXGdlIFxsYW1iZGFfMyBcZ2UgXGxhbWJkYV80IFxnZSAwJC4NCiogICRcbWF0aGJme1d9ID0gW1xtYXRoYmZ7d31fMSwgXG1hdGhiZnt3fV8yLCBcbWF0aGJme3d9XzMsIFxtYXRoYmZ7d31fNF0kIGlzIGFuIG9ydGhvZ29uYWwgbWF0cml4IHdob3NlIGNvbHVtbnMgYXJlIHRoZSBjb3JyZXNwb25kaW5nIGVpZ2VudmVjdG9ycy4NCg0KDQpUaGUgcHJpbmNpcGFsIGNvbXBvbmVudHMgZm9yIGFuIGluZGl2aWR1YWwgd2l0aCBjZW50ZXJlZCByZXNwb25zZSB2ZWN0b3IgJFxtYXRoYmZ7eX0kIGFyZSB0aGVuIGNvbXB1dGVkIGFzOg0KDQokJA0KXG1hdGhiZnt6fSA9IFxtYXRoYmZ7V31eVCBcbWF0aGJme3l9DQokJA0KDQpUaGUgJGskLXRoIFBDIHNjb3JlIGlzICR6X2sgPSBcbWF0aGJme3d9X2teVCBcbWF0aGJme3l9JC4NCg0KKio3LiBWYXJpYW5jZSBFeHBsYWluZWQqKg0KDQpUaGUgdG90YWwgdmFyaWFuY2UgaW4gdGhlIG9yaWdpbmFsIGRhdGEgaXMgdGhlIHN1bSBvZiB0aGUgdmFyaWFuY2VzIG9mIHRoZSBjZW50ZXJlZCB2YXJpYWJsZXMsIHdoaWNoIGlzIHRoZSB0cmFjZSBvZiAkXG1hdGhiZntTfSQuDQoNCiQkDQpcdGV4dHtUb3RhbCBWYXJpYW5jZX0gPSBcdGV4dHt0cn0oXG1hdGhiZntTfSkgPSBzX3sxMX1eMiArIHNfezIyfV4yICsgc197MzN9XjIgKyBzX3s0NH1eMg0KJCQNCg0KRm9yIGEgc3ltbWV0cmljIG1hdHJpeCwgdGhpcyBpcyBhbHNvIGVxdWFsIHRvIHRoZSBzdW0gb2YgaXRzIGVpZ2VudmFsdWVzOg0KDQokJA0KXHRleHR7VG90YWwgVmFyaWFuY2V9ID0gXGxhbWJkYV8xICsgXGxhbWJkYV8yICsgXGxhbWJkYV8zICsgXGxhbWJkYV80DQokJA0KVGhlIHByb3BvcnRpb24gb2YgdG90YWwgdmFyaWFuY2UgZXhwbGFpbmVkIGJ5IHRoZSAkayQtdGggcHJpbmNpcGFsIGNvbXBvbmVudCBpczoNCg0KJCQNClx0ZXh0e1Byb3BvcnRpb259X2sgPSBcZnJhY3tcbGFtYmRhX2t9e1xzdW1fe2k9MX1eezR9IFxsYW1iZGFfaX0NCiQkDQoNCg0KVGhlIGN1bXVsYXRpdmUgdmFyaWFuY2UgZXhwbGFpbmVkIGJ5IHRoZSBmaXJzdCAkbSQgY29tcG9uZW50cyBpczoNCg0KJCQNClx0ZXh0e0N1bXVsYXRpdmV9X20gPSBcZnJhY3tcc3VtX3tpPTF9XnttfSBcbGFtYmRhX2l9e1xzdW1fe2k9MX1eezR9IFxsYW1iZGFfaX0NCiQkDQoNCioqOC4gSW50ZXJwcmV0YXRpb24gaW4gb3VyIENvbnRleHQqKg0KDQpJbiB0aGUgY29udGV4dCBvZiBvdXIgbWF0aCBldmFsdWF0aW9uIGFueGlldHkgcXVlc3Rpb25uYWlyZToNCg0KKiAgVGhlIGxvYWRpbmcgdmVjdG9yICRcbWF0aGJme3d9XzEgPSBbd197MTF9LCB3X3sxMn0sIHdfezEzfSwgd197MTR9XV5UJCByZXZlYWxzIGhvdyB0aGUgb3JpZ2luYWwgaXRlbXMgY29tYmluZSB0byBmb3JtIHRoZSBwcmltYXJ5IGxhdGVudCBkaW1lbnNpb24gb2YgYW54aWV0eS4gRm9yIGV4YW1wbGUsIGlmIGFsbCBsb2FkaW5ncyBhcmUgcG9zaXRpdmUgYW5kIHNpbWlsYXIsICR6XzEkIG1pZ2h0IHJlcHJlc2VudCBcdGV4dGJme0dlbmVyYWwgTWF0aCBFdmFsdWF0aW9uIEFueGlldHl9Lg0KDQoqICBUaGUgc2Vjb25kIGNvbXBvbmVudCAkXG1hdGhiZnt3fV8yJCBtaWdodCBjb250cmFzdCBkaWZmZXJlbnQgdHlwZXMgb2YgYW54aWV0eS4gRm9yIGluc3RhbmNlLCBpZiAkd197MjF9JCBhbmQgJHdfezIyfSQgKHRlc3QtcmVsYXRlZCkgYXJlIHBvc2l0aXZlIHdoaWxlICR3X3syM30kIGFuZCAkd197MjR9JCAocG9wIHF1aXovaG9tZXdvcmspIGFyZSBuZWdhdGl2ZSwgJHpfMiQgbWlnaHQgcmVwcmVzZW50IFx0ZXh0YmZ7VGVzdCBBbnhpZXR5IHZzLiBTcG9udGFuZW91cyBFdmFsdWF0aW9uIEFueGlldHl9Lg0KKiAgQnkgZXhhbWluaW5nIHRoZSBsb2FkaW5ncywgd2UgY2FuIGludGVycHJldCB0aGUgdW5kZXJseWluZyBwc3ljaG9sb2dpY2FsIGNvbnN0cnVjdHMgdGhhdCBkcml2ZSB0aGUgY29ycmVsYXRpb25zIGJldHdlZW4gdGhlIGZvdXIgcXVlc3Rpb25uYWlyZSBpdGVtcy4NCg0KDQojIyBDb25maXJtYXRpY2UgRmFjdG9yIEFuYWx5c2lzIChDRkEpDQoNCg0KDQpUaGlzIGFwcGVuZGl4IHByb3ZpZGVzIGEgZGV0YWlsZWQgbWF0aGVtYXRpY2FsIGRlcml2YXRpb24gb2YgYSBDb25maXJtYXRvcnkgRmFjdG9yIEFuYWx5c2lzIChDRkEpIG1vZGVsLiBUaGUgb2JzZXJ2ZWQgdmFyaWFibGVzIGFyZSBuaW5lIGl0ZW1zIHJlbGF0ZWQgdG8gbWF0aGVtYXRpY2FsIGFueGlldHksIHdoaWNoIGFyZSBoeXBvdGhlc2l6ZWQgdG8gbG9hZCBvbnRvIHR3byBsYXRlbnQgZmFjdG9yczogXHRleHRiZntUZXN0IEFueGlldHkgKFRBKX0gYW5kIFx0ZXh0YmZ7TGVhcm5pbmcgQW54aWV0eSAoTEEpfS4NCg0KDQoqKjEuIExhdGVudCBGYWN0b3JzIGFuZCBPYnNlcnZlZCBWYXJpYWJsZXMqKg0KDQpXZSBkZWZpbmUgdHdvIGxhdGVudCBmYWN0b3JzOg0KDQoqICRcZXRhXzEkOiBUZXN0IEFueGlldHkgKFRBKQ0KKiAkXGV0YV8yJDogTGVhcm5pbmcgQW54aWV0eSAoTEEpDQoNCg0KV2UgaGF2ZSBuaW5lIG9ic2VydmVkIHZhcmlhYmxlcyAoaXRlbXMvcXVlc3Rpb25zKSwgJHlfMSQgdG8gJHlfOSQ6DQoNCiogJHlfMSQ6IEhhdmluZyB0byB1c2UgdGFibGVzIGluIHRoZSBiYWNrIG9mIGEgbWF0aCBib29rLg0KKiAkeV8yJDogVGhpbmtpbmcgYWJvdXQgYSBtYXRoIHRlc3QgdGhlIGRheSBiZWZvcmUgeW91IHRha2UgaXQuDQoqICR5XzMkOiBXYXRjaGluZyB0aGUgdGVhY2hlciB3b3JrIG91dCBhIG1hdGggcHJvYmxlbSBvbiB0aGUgYm9hcmQuDQoqICR5XzQkOiBUYWtpbmcgYSBtYXRoIHRlc3QuDQoqICR5XzUkOiBCZWluZyBnaXZlbiBhIGhvbWV3b3JrIGFzc2lnbm1lbnQgb2YgbWFueSBkaWZmaWN1bHQgcHJvYmxlbXMgdGhhdCBpcyBkdWUgZm9yIHRoZSBuZXh0IGNsYXNzIG1lZXRpbmcuDQoqICR5XzYkOiBMaXN0ZW5pbmcgdG8gYSBsZWN0dXJlIGluIG1hdGggY2xhc3MuDQoqICR5XzckOiBMaXN0ZW5pbmcgdG8gYW5vdGhlciBzdHVkZW50IGV4cGxhaW4gaG93IHRvIGRvIGEgbWF0aCBwcm9ibGVtLg0KKiAkeV84JDogQmVpbmcgZ2l2ZW4gYSBxdWl6IG9uIG1hdGggd2l0aG91dCBrbm93aW5nIGluIGFkdmFuY2UuDQoqICR5XzkkOiBTdGFydGluZyBhIG5ldyBjaGFwdGVyIGluIGEgbWF0aCBib29rLg0KIA0KDQoqKjIuIEZhY3RvciBMb2FkaW5ncyBhbmQgTW9kZWwgU3RydWN0dXJlKioNCg0KV2UgaHlwb3RoZXNpemUgdGhlIGZvbGxvd2luZyBmYWN0b3Igc3RydWN0dXJlOg0KDQoqIEZhY3RvciAkXGV0YV8xJCAoVGVzdCBBbnhpZXR5KSBsb2FkcyBvbiBpdGVtcyAkeV8yJCwgJHlfNCQsICR5XzUkLCBhbmQgJHlfOCQuDQoqIEZhY3RvciAkXGV0YV8yJCAoTGVhcm5pbmcgQW54aWV0eSkgbG9hZHMgb24gaXRlbXMgJHlfMSQsICR5XzMkLCAkeV82JCwgJHlfNyQsIGFuZCAkeV85JC4NCg0KDQpUaGUgZnVuZGFtZW50YWwgZXF1YXRpb24gZm9yIGEgQ0ZBIG1vZGVsIGZvciBhIHNpbmdsZSBvYnNlcnZlZCB2YXJpYWJsZSAkeV9pJCBpczoNCg0KJCQNCnlfaSA9IFxudV9pICsgXGxhbWJkYV97aTF9IFxldGFfMSArIFxsYW1iZGFfe2kyfSBcZXRhXzIgKyBcZXBzaWxvbl9pDQokJA0KDQp3aGVyZToNCg0KKiAkXG51X2kkIGlzIHRoZSBpbnRlcmNlcHQgZm9yIG9ic2VydmVkIHZhcmlhYmxlICR5X2kkLg0KKiAkXGxhbWJkYV97aTF9JCBpcyB0aGUgZmFjdG9yIGxvYWRpbmcgb2YgJHlfaSQgb24gbGF0ZW50IGZhY3RvciAkXGV0YV8xJC4NCiogJFxsYW1iZGFfe2kyfSQgaXMgdGhlIGZhY3RvciBsb2FkaW5nIG9mICR5X2kkIG9uIGxhdGVudCBmYWN0b3IgJFxldGFfMiQuDQoqICRcZXBzaWxvbl9pJCBpcyB0aGUgdW5pcXVlIGZhY3RvciAobWVhc3VyZW1lbnQgZXJyb3IpIGZvciAkeV9pJC4NCg0KDQoqKjMuIFRoZSBNZWFzdXJlbWVudCBNb2RlbCBpbiBNYXRyaXggRm9ybSoqDQoNClRoZSBtb2RlbCBmb3IgYWxsIG5pbmUgb2JzZXJ2ZWQgdmFyaWFibGVzIGNhbiBiZSB3cml0dGVuIGNvbXBhY3RseSBpbiBtYXRyaXggZm9ybS4gV2UgZGVmaW5lIHRoZSBmb2xsb3dpbmcgdmVjdG9ycyBhbmQgbWF0cmljZXM6DQoNCiogJFxtYXRoYmZ7eX0gPSAoeV8xLCB5XzIsIFxkb3RzLCB5XzkpXlQkIGlzIGEgJDkgXHRpbWVzIDEkIHZlY3RvciBvZiBvYnNlcnZlZCB2YXJpYWJsZXMuDQoqICRcYm9sZHN5bWJvbHtcbnV9ID0gKFxudV8xLCBcbnVfMiwgXGRvdHMsIFxudV85KV5UJCBpcyBhICQ5IFx0aW1lcyAxJCB2ZWN0b3Igb2YgaW50ZXJjZXB0cy4NCiogJFxib2xkc3ltYm9se1xldGF9ID0gKFxldGFfMSwgXGV0YV8yKV5UJCBpcyBhICQyIFx0aW1lcyAxJCB2ZWN0b3Igb2YgbGF0ZW50IGZhY3RvcnMuDQoqICRcYm9sZHN5bWJvbHtcTGFtYmRhfSQgaXMgYSAkOSBcdGltZXMgMiQgbWF0cml4IG9mIGZhY3RvciBsb2FkaW5ncyAkXGxhbWJkYV97aWp9JC4NCiogJFxib2xkc3ltYm9se1xlcHNpbG9ufSA9IChcZXBzaWxvbl8xLCBcZXBzaWxvbl8yLCBcZG90cywgXGVwc2lsb25fOSleVCQgaXMgYSAkOSBcdGltZXMgMSQgdmVjdG9yIG9mIG1lYXN1cmVtZW50IGVycm9ycy4NCg0KDQpUaGUgZnVsbCBtZWFzdXJlbWVudCBtb2RlbCBpczoNCg0KJCQNClxtYXRoYmZ7eX0gPSBcYm9sZHN5bWJvbHtcbnV9ICsgXGJvbGRzeW1ib2x7XExhbWJkYX0gXGJvbGRzeW1ib2x7XGV0YX0gKyBcYm9sZHN5bWJvbHtcZXBzaWxvbn0NCiQkDQoNCkdpdmVuIG91ciBoeXBvdGhlc2l6ZWQgZmFjdG9yIHN0cnVjdHVyZSwgdGhlIGxvYWRpbmcgbWF0cml4ICRcYm9sZHN5bWJvbHtcTGFtYmRhfSQgaGFzIGEgc3BlY2lmaWMgZm9ybSB3aXRoIG1hbnkgZWxlbWVudHMgZml4ZWQgdG8gemVyby4gVG8gZW5zdXJlIG1vZGVsIGlkZW50aWZpY2F0aW9uLCB3ZSBuZWVkIHRvIHNldCB0aGUgc2NhbGUgb2YgZWFjaCBsYXRlbnQgdmFyaWFibGUuIFRoaXMgaXMgdHlwaWNhbGx5IGRvbmUgYnkgXHRleHRiZntmYWN0b3Igc3RhbmRhcmRpemF0aW9ufSwgd2hlcmUgdGhlIHZhcmlhbmNlIG9mIHRoZSBsYXRlbnQgZmFjdG9yIGlzIGZpeGVkIHRvIDEsIG9yIGJ5IFx0ZXh0YmZ7bWFya2VyIHZhcmlhYmxlfSBtZXRob2QsIHdoZXJlIG9uZSBsb2FkaW5nIHBlciBmYWN0b3IgaXMgZml4ZWQgdG8gMS4gV2Ugd2lsbCB1c2UgdGhlIGxhdHRlci4NCg0KTGV0IHVzIGRlZmluZToNCg0KKiAkeV8yJCBhcyB0aGUgbWFya2VyIHZhcmlhYmxlIGZvciAkXGV0YV8xJCAoVGVzdCBBbnhpZXR5KSwgc28gJFxsYW1iZGFfezIxfSA9IDEkLg0KKiAkeV8xJCBhcyB0aGUgbWFya2VyIHZhcmlhYmxlIGZvciAkXGV0YV8yJCAoTGVhcm5pbmcgQW54aWV0eSksIHNvICRcbGFtYmRhX3sxMn0gPSAxJC4NCg0KDQpUaGUgJFxib2xkc3ltYm9se1xMYW1iZGF9JCBtYXRyaXggaXMgdGhlbjoNCg0KJCQNClxib2xkc3ltYm9se1xMYW1iZGF9ID0NClxiZWdpbntibWF0cml4fQ0KMCAmIDEgXFwgICAgICAgICAgICAgICUgeTEgbG9hZHMgb24gZXRhMiAoTEEpDQoxICYgMCBcXCAgICAgICAgICAgICAgJSB5MiBsb2FkcyBvbiBldGExIChUQSkNCjAgJiBcbGFtYmRhX3szMn0gXFwgICAlIHkzIGxvYWRzIG9uIGV0YTIgKExBKQ0KXGxhbWJkYV97NDF9ICYgMCBcXCAgICUgeTQgbG9hZHMgb24gZXRhMSAoVEEpDQpcbGFtYmRhX3s1MX0gJiAwIFxcICAgJSB5NSBsb2FkcyBvbiBldGExIChUQSkNCjAgJiBcbGFtYmRhX3s2Mn0gXFwgICAlIHk2IGxvYWRzIG9uIGV0YTIgKExBKQ0KMCAmIFxsYW1iZGFfezcyfSBcXCAgICUgeTcgbG9hZHMgb24gZXRhMiAoTEEpDQpcbGFtYmRhX3s4MX0gJiAwIFxcICAgJSB5OCBsb2FkcyBvbiBldGExIChUQSkNCjAgJiBcbGFtYmRhX3s5Mn0gXFwgICAlIHk5IGxvYWRzIG9uIGV0YTIgKExBKQ0KXGVuZHtibWF0cml4fQ0KJCQNCg0KDQoqKjQuIE1vZGVsIEFzc3VtcHRpb25zKioNCg0KVGhlIENGQSBtb2RlbCByZWxpZXMgb24gc2V2ZXJhbCBrZXkgYXNzdW1wdGlvbnM6DQoNCiogVGhlIGVycm9ycyBoYXZlIGEgbWVhbiBvZiB6ZXJvOiAkRShcYm9sZHN5bWJvbHtcZXBzaWxvbn0pID0gXG1hdGhiZnswfSQuDQogICAgXGl0ZW0gVGhlIGVycm9ycyBhcmUgdW5jb3JyZWxhdGVkIHdpdGggdGhlIGZhY3RvcnM6ICRcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XGV0YX0sIFxib2xkc3ltYm9se1xlcHNpbG9ufSkgPSBcbWF0aGJmezB9JC4NCiAgICANCiogVGhlIGVycm9ycyBtYXkgYmUgY29ycmVsYXRlZCB3aXRoIGVhY2ggb3RoZXIsIGJ1dCBpbiBhIGJhc2ljIG1vZGVsLCB3ZSBvZnRlbiBhc3N1bWUgdGhleSBhcmUgdW5jb3JyZWxhdGVkOiAkXGJvbGRzeW1ib2x7XFRoZXRhfV97XGVwc2lsb259ID0gXG1hdGhybXtDb3Z9KFxib2xkc3ltYm9se1xlcHNpbG9ufSkgPSBcbWF0aHJte2RpYWd9KFx0aGV0YV97MTF9LCBcdGhldGFfezIyfSwgXGRvdHMsIFx0aGV0YV97OTl9KSQsIHdoZXJlICRcdGhldGFfe2lpfSA9IFxtYXRocm17VmFyfShcZXBzaWxvbl9pKSQuDQoNCg0KKio1LiBEZXJpdmF0aW9uIG9mIHRoZSBJbXBsaWVkIENvdmFyaWFuY2UgTWF0cml4KioNCg0KVGhlIGNvcmUgb2YgQ0ZBIGlzIHRvIG1vZGVsIHRoZSBwb3B1bGF0aW9uIGNvdmFyaWFuY2UgbWF0cml4IG9mIHRoZSBvYnNlcnZlZCB2YXJpYWJsZXMsICRcYm9sZHN5bWJvbHtcU2lnbWF9JC4gVGhlIG1vZGVsLWltcGxpZWQgY292YXJpYW5jZSBtYXRyaXgsIGRlbm90ZWQgJFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkkLCBpcyBhIGZ1bmN0aW9uIG9mIHRoZSBtb2RlbCBwYXJhbWV0ZXJzICRcYm9sZHN5bWJvbHtcdGhldGF9JCAobG9hZGluZ3MsIGZhY3RvciB2YXJpYW5jZXMvY292YXJpYW5jZXMsIGVycm9yIHZhcmlhbmNlcykuDQoNCkxldCAkXGJvbGRzeW1ib2x7XFBzaX0kIGJlIHRoZSAkMiBcdGltZXMgMiQgY292YXJpYW5jZSBtYXRyaXggb2YgdGhlIGxhdGVudCBmYWN0b3JzOg0KDQokJA0KXGJvbGRzeW1ib2x7XFBzaX0gPSBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XGV0YX0pID0NClxiZWdpbntibWF0cml4fQ0KXHBzaV97MTF9ICYgXHBzaV97MTJ9IFxcDQpccHNpX3syMX0gJiBccHNpX3syMn0NClxlbmR7Ym1hdHJpeH0NCj0NClxiZWdpbntibWF0cml4fQ0KXG1hdGhybXtWYXJ9KFxldGFfMSkgJiBcbWF0aHJte0Nvdn0oXGV0YV8xLCBcZXRhXzIpIFxcDQpcbWF0aHJte0Nvdn0oXGV0YV8xLCBcZXRhXzIpICYgXG1hdGhybXtWYXJ9KFxldGFfMikNClxlbmR7Ym1hdHJpeH0NCiQkDQoNCg0KDQpUaGUgaW1wbGllZCBjb3ZhcmlhbmNlIG1hdHJpeCAkXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KSQgaXMgZGVyaXZlZCBhcyBmb2xsb3dzOg0KDQokJA0KXGJlZ2lue2FsaWduKn0NClxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkgJj0gXG1hdGhybXtDb3Z9KFxtYXRoYmZ7eX0pIFxcDQomPSBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XG51fSArIFxib2xkc3ltYm9se1xMYW1iZGF9XGJvbGRzeW1ib2x7XGV0YX0gKyBcYm9sZHN5bWJvbHtcZXBzaWxvbn0pIFxcDQomPSBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XExhbWJkYX1cYm9sZHN5bWJvbHtcZXRhfSArIFxib2xkc3ltYm9se1xlcHNpbG9ufSkgXHF1YWQgXHRleHR7KHNpbmNlIH0gXGJvbGRzeW1ib2x7XG51fSBcdGV4dHsgaXMgYSBjb25zdGFudCl9IFxcDQomPSBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XExhbWJkYX1cYm9sZHN5bWJvbHtcZXRhfSkgKyBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XGVwc2lsb259KSArIFxtYXRocm17Q292fShcYm9sZHN5bWJvbHtcTGFtYmRhfVxib2xkc3ltYm9se1xldGF9LCBcYm9sZHN5bWJvbHtcZXBzaWxvbn0pICsgXG1hdGhybXtDb3Z9KFxib2xkc3ltYm9se1xlcHNpbG9ufSwgXGJvbGRzeW1ib2x7XExhbWJkYX1cYm9sZHN5bWJvbHtcZXRhfSkNClxlbmR7YWxpZ24qfQ0KJCQNCg0KDQoNClVzaW5nIGFzc3VtcHRpb24gMiAoJFxtYXRocm17Q292fShcYm9sZHN5bWJvbHtcZXRhfSwgXGJvbGRzeW1ib2x7XGVwc2lsb259KSA9IFxtYXRoYmZ7MH0kKSwgdGhlIGNyb3NzLXRlcm1zIHZhbmlzaDoNCg0KJCQNClxtYXRocm17Q292fShcYm9sZHN5bWJvbHtcTGFtYmRhfVxib2xkc3ltYm9se1xldGF9LCBcYm9sZHN5bWJvbHtcZXBzaWxvbn0pID0gXGJvbGRzeW1ib2x7XExhbWJkYX0gXG1hdGhybXtDb3Z9KFxib2xkc3ltYm9se1xldGF9LCBcYm9sZHN5bWJvbHtcZXBzaWxvbn0pID0gXG1hdGhiZnswfSwgXHF1YWQgXG1hdGhybXtDb3Z9KFxib2xkc3ltYm9se1xlcHNpbG9ufSwgXGJvbGRzeW1ib2x7XExhbWJkYX1cYm9sZHN5bWJvbHtcZXRhfSkgPSBcbWF0aGJmezB9DQokJA0KDQoNClRoZXJlZm9yZSwNCg0KJCQNClxiZWdpbnthbGlnbip9DQpcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pICY9IFxtYXRocm17Q292fShcYm9sZHN5bWJvbHtcTGFtYmRhfVxib2xkc3ltYm9se1xldGF9KSArIFxtYXRocm17Q292fShcYm9sZHN5bWJvbHtcZXBzaWxvbn0pIFxcDQomPSBcYm9sZHN5bWJvbHtcTGFtYmRhfSBcbWF0aHJte0Nvdn0oXGJvbGRzeW1ib2x7XGV0YX0pIFxib2xkc3ltYm9se1xMYW1iZGF9XlQgKyBcYm9sZHN5bWJvbHtcVGhldGF9X3tcZXBzaWxvbn0gXFwNCiY9IFxib2xkc3ltYm9se1xMYW1iZGF9IFxib2xkc3ltYm9se1xQc2l9IFxib2xkc3ltYm9se1xMYW1iZGF9XlQgKyBcYm9sZHN5bWJvbHtcVGhldGF9X3tcZXBzaWxvbn0NClxlbmR7YWxpZ24qfQ0KJCQNCg0KDQpUaGlzIGlzIHRoZSBmdW5kYW1lbnRhbCBlcXVhdGlvbiBmb3IgdGhlIGltcGxpZWQgY292YXJpYW5jZSBtYXRyaXggaW4gQ0ZBOg0KDQokJA0KXGJveGVke1xib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkgPSBcYm9sZHN5bWJvbHtcTGFtYmRhfSBcYm9sZHN5bWJvbHtcUHNpfSBcYm9sZHN5bWJvbHtcTGFtYmRhfV5UICsgXGJvbGRzeW1ib2x7XFRoZXRhfV97XGVwc2lsb259fQ0KJCQNCg0KKio2LiBQYXJhbWV0ZXIgRXN0aW1hdGlvbiBhbmQgTW9kZWwgSWRlbnRpZmljYXRpb24qKg0KDQpUaGUgZ29hbCBvZiBlc3RpbWF0aW9uIGlzIHRvIGZpbmQgcGFyYW1ldGVyIHZhbHVlcyAkXGhhdHtcYm9sZHN5bWJvbHtcdGhldGF9fSQgc3VjaCB0aGF0ICRcYm9sZHN5bWJvbHtcU2lnbWF9KFxoYXR7XGJvbGRzeW1ib2x7XHRoZXRhfX0pJCBpcyBhcyBjbG9zZSBhcyBwb3NzaWJsZSB0byB0aGUgc2FtcGxlIGNvdmFyaWFuY2UgbWF0cml4ICRcbWF0aGJme1N9JCBvYnRhaW5lZCBmcm9tIHRoZSBkYXRhLg0KDQpGb3IgaWRlbnRpZmljYXRpb24sIHRoZSBudW1iZXIgb2YgZnJlZSBwYXJhbWV0ZXJzICR0JCBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIG5vbi1yZWR1bmRhbnQgZWxlbWVudHMgaW4gJFxtYXRoYmZ7U30kLCB3aGljaCBpcyAkXGZyYWN7cChwKzEpfXsyfSQgd2hlcmUgJHAkIGlzIHRoZSBudW1iZXIgb2Ygb2JzZXJ2ZWQgdmFyaWFibGVzICgkcD05JCkuDQoNCkxldCdzIGNvdW50IG91ciBmcmVlIHBhcmFtZXRlcnMgJHQkOg0KDQoqICoqRmFjdG9yIExvYWRpbmdzKiogKCRcYm9sZHN5bWJvbHtcTGFtYmRhfSQpfTogV2UgZml4ZWQgJFxsYW1iZGFfezIxfSQgYW5kICRcbGFtYmRhX3sxMn0kIHRvIDEuIFdlIGhhdmUgNyBmcmVlIGxvYWRpbmdzOiAkXGxhbWJkYV97MzJ9JCwgJFxsYW1iZGFfezQxfSQsICRcbGFtYmRhX3s1MX0kLCAkXGxhbWJkYV97NjJ9JCwgJFxsYW1iZGFfezcyfSQsICRcbGFtYmRhX3s4MX0kLCAkXGxhbWJkYV97OTJ9JC4NCg0KKiAqKkxhdGVudCBGYWN0b3IgQ292YXJpYW5jZXMqKiAoJFxib2xkc3ltYm9se1xQc2l9JCl9OiBXZSBoYXZlIDMgZnJlZSBwYXJhbWV0ZXJzOiAkXHBzaV97MTF9JCAodmFyaWFuY2Ugb2YgVEEpLCAkXHBzaV97MjJ9JCAodmFyaWFuY2Ugb2YgTEEpLCBhbmQgJFxwc2lfezEyfSQgKGNvdmFyaWFuY2UgYmV0d2VlbiBUQSBhbmQgTEEpLg0KDQoqICoqRXJyb3IgVmFyaWFuY2VzKiogKCRcYm9sZHN5bWJvbHtcVGhldGF9X3tcZXBzaWxvbn0kKX06IFdlIGhhdmUgOSBmcmVlIHBhcmFtZXRlcnM6ICRcdGhldGFfezExfSwgXHRoZXRhX3syMn0sIFxkb3RzLCBcdGhldGFfezk5fSQuDQoNCg0KVG90YWwgZnJlZSBwYXJhbWV0ZXJzOiAkdCA9IDcgKyAzICsgOSA9IDE5JC4NCg0KVGhlIG51bWJlciBvZiBub24tcmVkdW5kYW50IGVsZW1lbnRzIGluICRcbWF0aGJme1N9JCBpcyAkXGZyYWN7OSBcdGltZXMgKDkrMSl9ezJ9ID0gNDUkLg0KDQpTaW5jZSAkNDUgPiAxOSQsIHRoZSBtb2RlbCBpcyBcdGV4dGJme292ZXItaWRlbnRpZmllZH0gd2l0aCAkZGYgPSA0NSAtIDE5ID0gMjYkIGRlZ3JlZXMgb2YgZnJlZWRvbS4gVGhpcyBpcyBhIG5lY2Vzc2FyeSBjb25kaXRpb24gZm9yIGlkZW50aWZpY2F0aW9uLCBhbmQgd2l0aCB0aGUgc2NhbGluZyBjb25zdHJhaW50cyB3ZSBwbGFjZWQsIHRoZSBtb2RlbCBpcyBpZGVudGlmaWVkLg0KDQoqKjcuIENvbmNsdXNpb24qKg0KDQpUaGlzIGRlcml2YXRpb24gaGFzIG91dGxpbmVkIHRoZSBjb21wbGV0ZSBtYXRoZW1hdGljYWwgc2V0dXAgZm9yIGEgdHdvLWZhY3RvciBDRkEgbW9kZWwgb2YgbWF0aGVtYXRpY2FsIGFueGlldHkuIFRoZSBtb2RlbCBwb3NpdHMgdGhhdCB0aGUgY292YXJpYXRpb24gYW1vbmcgdGhlIG5pbmUgb2JzZXJ2ZWQgaXRlbXMgY2FuIGJlIGV4cGxhaW5lZCBieSB0d28gY29ycmVsYXRlZCBsYXRlbnQgZmFjdG9ycy4gVGhlIG5leHQgc3RlcCB3b3VsZCBiZSB0byB1c2UgYW4gZXN0aW1hdGlvbiBhbGdvcml0aG0gKGUuZy4sIE1heGltdW0gTGlrZWxpaG9vZCkgdG8gZmluZCB0aGUgcGFyYW1ldGVyIHZhbHVlcyB0aGF0IG1pbmltaXplIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gJFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkkIGFuZCB0aGUgc2FtcGxlIGNvdmFyaWFuY2UgbWF0cml4ICRcbWF0aGJme1N9JCwgYW5kIHRoZW4gYXNzZXNzIHRoZSBtb2RlbCdzIGZpdCB0byB0aGUgZGF0YS4NCg0KDQoNCg0KDQojIyBNYXRoZW1hdGljYWwgRm9ybXVsYXRpb24gb2YgU0VNIE1vZGVsIA0KDQoNCioqMS4gTW9kZWwgU3BlY2lmaWNhdGlvbioqDQoNCkxldCB0aGUgbW9kZWwgY29uc2lzdCBvZiB0aGUgZm9sbG93aW5nIGNvbXBvbmVudHM6DQoNCg0KKiAqKkV4b2dlbm91cyBsYXRlbnQgdmFyaWFibGVzKio6ICRcYm9sZHN5bWJvbHtceGl9ID0gKFx4aV8xLCBceGlfMileVCQsIHdoZXJlOg0KICArICRceGlfMSQ6IFRlYWNoZXItY2VudGVyZWQNCiAgKyAkXHhpXzIkOiBTdHVkZW50LWNlbnRlcmVkDQoqICoqRW5kb2dlbm91cyBsYXRlbnQgdmFyaWFibGVzKio6ICRcYm9sZHN5bWJvbHtcZXRhfSA9IChcZXRhXzEsIFxldGFfMileVCQsIHdoZXJlOg0KICArICRcZXRhXzEkOiBNYXRoIEV2YWx1YXRpb24gQW54aWV0eSAoTUVBKQ0KICArICRcZXRhXzIkOiBNYXRoIExlYXJuaW5nIEFueGlldHkgKE1MQSkNCiogKipPYnNlcnZlZCBpbmRpY2F0b3JzIGZvciBUZWFjaGVyLWNlbnRlcmVkKio6ICRcbWF0aGJme3h9XzEgPSAoeF8xLCB4XzIsIHhfMywgeF80KV5UJCB3aGVyZToNCiAgKyAkeF8xJDogRGVkdWN0aXZlDQogICsgJHhfMiQ6IExlY3R1cmUNCiAgKyAkeF8zJDogRGVtb25zdHJhdGlvbg0KICArICR4XzQkOiBSZXBldGl0aXZlDQoqICoqT2JzZXJ2ZWQgaW5kaWNhdG9ycyBmb3IgU3R1ZGVudC1jZW50ZXJlZCoqOiAkXG1hdGhiZnt4fV8yID0gKHhfNSwgeF82LCB4XzcpXlQkIHdoZXJlOg0KICArICR4XzUkOiBDb29wZXJhdGl2ZQ0KICArICR4XzYkOiBJbmR1Y3RpdmUNCiAgKyAkeF83JDogSW50ZWdyYXRpdmUNCiogKipPYnNlcnZlZCBpbmRpY2F0b3JzIGZvciBNRUEqKjogJFxtYXRoYmZ7eX1fMSA9ICh5XzEsIHlfMiwgeV8zLCB5XzQpXlQkIChNRUExLU1FQTQpDQoqICoqT2JzZXJ2ZWQgaW5kaWNhdG9ycyBmb3IgTUxBKio6ICRcbWF0aGJme3l9XzIgPSAoeV81LCB5XzYsIHlfNywgeV84LCB5XzkpXlQkIChNTEExLCBNTEEzLCBNTEE2LCBNTEE3LCBNTEE5KQ0KKiAqKkV4b2dlbm91cyBvYnNlcnZlZCB2YXJpYWJsZXMqKjogJFxtYXRoYmZ7d30gPSAod18xLCB3XzIsIHdfMywgd180LCB3XzUpXlQkIHdoZXJlOg0KICArICR3XzEkOiBTZWxmLWVmZmljYWN5DQogICsgJHdfMiQ6IFRlY2hub2xvZ3kNCiAgKyAkd18zJDogRW5nYWdlbWVudA0KICArICR3XzQkOiBHZW5kZXINCiAgKyAkd181JDogUmVzb3VyY2UNCg0KDQoqKjIuIE1lYXN1cmVtZW50IE1vZGVscyoqDQoNCg0KKkZvciBleG9nZW5vdXMgbGF0ZW50IHZhcmlhYmxlczoqDQoNCiQkDQpcYmVnaW57YWxpZ24qfQ0KXG1hdGhiZnt4fSAmPSBcYm9sZHN5bWJvbHtcTGFtYmRhfV94IFxib2xkc3ltYm9se1x4aX0gKyBcYm9sZHN5bWJvbHtcZGVsdGF9IFxcDQpcYmVnaW57Ym1hdHJpeH0NCnhfMSBcXCB4XzIgXFwgeF8zIFxcIHhfNCBcXCB4XzUgXFwgeF82IFxcIHhfNw0KXGVuZHtibWF0cml4fQ0KJj0NClxiZWdpbntibWF0cml4fQ0KXGxhbWJkYV97MSwxfSAmIDAgXFwNClxsYW1iZGFfezIsMX0gJiAwIFxcDQpcbGFtYmRhX3szLDF9ICYgMCBcXA0KXGxhbWJkYV97NCwxfSAmIDAgXFwNCjAgJiBcbGFtYmRhX3s1LDJ9IFxcDQowICYgXGxhbWJkYV97NiwyfSBcXA0KMCAmIFxsYW1iZGFfezcsMn0NClxlbmR7Ym1hdHJpeH0NClxiZWdpbntibWF0cml4fQ0KXHhpXzEgXFwgXHhpXzINClxlbmR7Ym1hdHJpeH0NCisNClxiZWdpbntibWF0cml4fQ0KXGRlbHRhXzEgXFwgXGRlbHRhXzIgXFwgXGRlbHRhXzMgXFwgXGRlbHRhXzQgXFwgXGRlbHRhXzUgXFwgXGRlbHRhXzYgXFwgXGRlbHRhXzcNClxlbmR7Ym1hdHJpeH0NClxlbmR7YWxpZ24qfQ0KJCQNCg0KDQoqRm9yIGVuZG9nZW5vdXMgbGF0ZW50IHZhcmlhYmxlczoqDQoNCiQkDQpcYmVnaW57YWxpZ24qfQ0KXG1hdGhiZnt5fSAmPSBcYm9sZHN5bWJvbHtcTGFtYmRhfV95IFxib2xkc3ltYm9se1xldGF9ICsgXGJvbGRzeW1ib2x7XGVwc2lsb259IFxcDQpcYmVnaW57Ym1hdHJpeH0NCnlfMSBcXCB5XzIgXFwgeV8zIFxcIHlfNCBcXCB5XzUgXFwgeV82IFxcIHlfNyBcXCB5XzggXFwgeV85DQpcZW5ke2JtYXRyaXh9DQomPQ0KXGJlZ2lue2JtYXRyaXh9DQpcbGFtYmRhX3sxLDF9XnkgJiAwIFxcDQpcbGFtYmRhX3syLDF9XnkgJiAwIFxcDQpcbGFtYmRhX3szLDF9XnkgJiAwIFxcDQpcbGFtYmRhX3s0LDF9XnkgJiAwIFxcDQowICYgXGxhbWJkYV97NSwyfV55IFxcDQowICYgXGxhbWJkYV97NiwyfV55IFxcDQowICYgXGxhbWJkYV97NywyfV55IFxcDQowICYgXGxhbWJkYV97OCwyfV55IFxcDQowICYgXGxhbWJkYV97OSwyfV55DQpcZW5ke2JtYXRyaXh9DQpcYmVnaW57Ym1hdHJpeH0NClxldGFfMSBcXCBcZXRhXzINClxlbmR7Ym1hdHJpeH0NCisNClxiZWdpbntibWF0cml4fQ0KXGVwc2lsb25fMSBcXCBcZXBzaWxvbl8yIFxcIFxlcHNpbG9uXzMgXFwgXGVwc2lsb25fNCBcXCBcZXBzaWxvbl81IFxcIA0KXGVwc2lsb25fNiBcXCBcZXBzaWxvbl83IFxcIFxlcHNpbG9uXzggXFwgXGVwc2lsb25fOQ0KXGVuZHtibWF0cml4fQ0KXGVuZHthbGlnbip9DQokJA0KDQoNCg0KKiozLiBTdHJ1Y3R1cmFsIE1vZGVsKioNCg0KVGhlIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBsYXRlbnQgYW5kIG9ic2VydmVkIHZhcmlhYmxlczoNCg0KJCQNClxiZWdpbnthbGlnbip9DQpcYm9sZHN5bWJvbHtcZXRhfSAmPSBcbWF0aGJme0J9IFxib2xkc3ltYm9se1xldGF9ICsgXGJvbGRzeW1ib2x7XEdhbW1hfSBcYm9sZHN5bWJvbHtceGl9ICsgXGJvbGRzeW1ib2x7XEdhbW1hfV93IFxtYXRoYmZ7d30gKyBcYm9sZHN5bWJvbHtcemV0YX0gXFwNClxiZWdpbntibWF0cml4fQ0KXGV0YV8xIFxcIFxldGFfMg0KXGVuZHtibWF0cml4fQ0KJj0NClxiZWdpbntibWF0cml4fQ0KMCAmIDAgXFwNClxiZXRhX3syMX0gJiAwDQpcZW5ke2JtYXRyaXh9DQpcYmVnaW57Ym1hdHJpeH0NClxldGFfMSBcXCBcZXRhXzINClxlbmR7Ym1hdHJpeH0NCisNClxiZWdpbntibWF0cml4fQ0KXGdhbW1hX3sxMX0gJiBcZ2FtbWFfezEyfSBcXA0KXGdhbW1hX3syMX0gJiBcZ2FtbWFfezIyfQ0KXGVuZHtibWF0cml4fQ0KXGJlZ2lue2JtYXRyaXh9DQpceGlfMSBcXCBceGlfMg0KXGVuZHtibWF0cml4fQ0KKw0KXGJlZ2lue2JtYXRyaXh9DQpcZ2FtbWFfezEzfSAmIFxnYW1tYV97MTR9ICYgXGdhbW1hX3sxNX0gJiBcZ2FtbWFfezE2fSAmIFxnYW1tYV97MTd9IFxcDQpcZ2FtbWFfezIzfSAmIFxnYW1tYV97MjR9ICYgXGdhbW1hX3syNX0gJiBcZ2FtbWFfezI2fSAmIFxnYW1tYV97Mjd9DQpcZW5ke2JtYXRyaXh9DQpcYmVnaW57Ym1hdHJpeH0NCndfMSBcXCB3XzIgXFwgd18zIFxcIHdfNCBcXCB3XzUNClxlbmR7Ym1hdHJpeH0NCisNClxiZWdpbntibWF0cml4fQ0KXHpldGFfMSBcXCBcemV0YV8yDQpcZW5ke2JtYXRyaXh9DQpcZW5ke2FsaWduKn0NCiQkDQoNCg0KKio0LiBBc3N1bXB0aW9ucyoqDQoNCiogIFRoZSBtZWFzdXJlbWVudCBlcnJvcnMgYXJlIHVuY29ycmVsYXRlZCB3aXRoIHRoZSBsYXRlbnQgdmFyaWFibGVzOg0KDQokJA0KICAgIFxiZWdpbnthbGlnbip9DQogICAgRShcYm9sZHN5bWJvbHtcZGVsdGF9fFxib2xkc3ltYm9se1x4aX0pID0gXG1hdGhiZnswfSwgXHF1YWQgRShcYm9sZHN5bWJvbHtcZXBzaWxvbn18XGJvbGRzeW1ib2x7XGV0YX0pID0gXG1hdGhiZnswfQ0KICAgIFxlbmR7YWxpZ24qfQ0KJCQgICAgDQoNCiogVGhlIHN0cnVjdHVyYWwgZGlzdHVyYmFuY2VzIGhhdmUgemVybyBtZWFuIGFuZCBhcmUgdW5jb3JyZWxhdGVkIHdpdGggdGhlIGV4b2dlbm91cyB2YXJpYWJsZXM6DQoNCiQkDQogICAgXGJlZ2lue2FsaWduKn0NCiAgICBFKFxib2xkc3ltYm9se1x6ZXRhfSkgPSBcbWF0aGJmezB9LCBccXVhZCBcdGV4dHtDb3Z9KFxib2xkc3ltYm9se1x6ZXRhfSwgXGJvbGRzeW1ib2x7XHhpfSkgPSBcbWF0aGJmezB9LCBccXVhZCBcdGV4dHtDb3Z9KFxib2xkc3ltYm9se1x6ZXRhfSwgXG1hdGhiZnt3fSkgPSBcbWF0aGJmezB9DQogICAgXGVuZHthbGlnbip9DQokJA0KICAgIA0KKiBUaGUgbWVhc3VyZW1lbnQgZXJyb3JzIGFuZCBzdHJ1Y3R1cmFsIGRpc3R1cmJhbmNlcyBhcmUgbXV0dWFsbHkgdW5jb3JyZWxhdGVkOg0KICAgIA0KJCQNCiAgICBcYmVnaW57YWxpZ24qfQ0KICAgIFx0ZXh0e0Nvdn0oXGJvbGRzeW1ib2x7XGRlbHRhfSwgXGJvbGRzeW1ib2x7XGVwc2lsb259KSA9IFxtYXRoYmZ7MH0sIFxxdWFkIFx0ZXh0e0Nvdn0oXGJvbGRzeW1ib2x7XGRlbHRhfSwgXGJvbGRzeW1ib2x7XHpldGF9KSA9IFxtYXRoYmZ7MH0sIFxxdWFkIFx0ZXh0e0Nvdn0oXGJvbGRzeW1ib2x7XGVwc2lsb259LCBcYm9sZHN5bWJvbHtcemV0YX0pID0gXG1hdGhiZnswfQ0KICAgIFxlbmR7YWxpZ24qfQ0KJCQNCiAgICANCiogVGhlIG1lYXN1cmVtZW50IGVycm9ycyBhcmUgbXV0dWFsbHkgdW5jb3JyZWxhdGVkOg0KDQokJA0KICAgIFxiZWdpbnthbGlnbip9DQogICAgXHRleHR7Q292fShcYm9sZHN5bWJvbHtcZGVsdGF9KSA9IFxib2xkc3ltYm9se1xUaGV0YX1fe1xkZWx0YX0gPSBcdGV4dHtkaWFnfShcdGhldGFfe1xkZWx0YSwxfSwgXGRvdHMsIFx0aGV0YV97XGRlbHRhLDd9KQ0KICAgIFxlbmR7YWxpZ24qfQ0KJCQNCg0KDQokJA0KICAgIFxiZWdpbnthbGlnbip9DQogICAgXHRleHR7Q292fShcYm9sZHN5bWJvbHtcZXBzaWxvbn0pID0gXGJvbGRzeW1ib2x7XFRoZXRhfV97XGVwc2lsb259ID0gXHRleHR7ZGlhZ30oXHRoZXRhX3tcZXBzaWxvbiwxfSwgXGRvdHMsIFx0aGV0YV97XGVwc2lsb24sOX0pDQogICAgXGVuZHthbGlnbip9DQokJA0KDQoqIFRoZSBzdHJ1Y3R1cmFsIGRpc3R1cmJhbmNlcyBoYXZlIGNvdmFyaWFuY2UgbWF0cml4Og0KICAgIA0KJCQNCiAgICBcYmVnaW57YWxpZ24qfQ0KICAgIFx0ZXh0e0Nvdn0oXGJvbGRzeW1ib2x7XHpldGF9KSA9IFxib2xkc3ltYm9se1xQc2l9ID0gDQogICAgXGJlZ2lue2JtYXRyaXh9DQogICAgXHBzaV97MTF9ICYgXHBzaV97MTJ9IFxcDQogICAgXHBzaV97MjF9ICYgXHBzaV97MjJ9DQogICAgXGVuZHtibWF0cml4fQ0KICAgIFxlbmR7YWxpZ24qfQ0KJCQgICAgDQogICAgDQoqIFRoZSBleG9nZW5vdXMgbGF0ZW50IHZhcmlhYmxlcyBoYXZlIGNvdmFyaWFuY2UgbWF0cml4Og0KDQokJA0KICAgIFxiZWdpbnthbGlnbip9DQogICAgXHRleHR7Q292fShcYm9sZHN5bWJvbHtceGl9KSA9IFxib2xkc3ltYm9se1xQaGl9ID0gDQogICAgXGJlZ2lue2JtYXRyaXh9DQogICAgXHBoaV97MTF9ICYgXHBoaV97MTJ9IFxcDQogICAgXHBoaV97MjF9ICYgXHBoaV97MjJ9DQogICAgXGVuZHtibWF0cml4fQ0KICAgIFxlbmR7YWxpZ24qfQ0KJCQNCg0KKiBUaGUgZXhvZ2Vub3VzIG9ic2VydmVkIHZhcmlhYmxlcyBoYXZlIGNvdmFyaWFuY2UgbWF0cml4Og0KDQokJA0KICAgIFxiZWdpbnthbGlnbip9DQogICAgXHRleHR7Q292fShcbWF0aGJme3d9KSA9IFxib2xkc3ltYm9se1xQaGl9X3cNCiAgICBcZW5ke2FsaWduKn0NCiQkDQoNCg0KKiBBbGwgdmFyaWFibGVzIGFyZSBtdWx0aXZhcmlhdGUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuDQoNCg0KKio1LiBJbXBsaWVkIENvdmFyaWFuY2UgTWF0cml4KioNCg0KTGV0ICRcYm9sZHN5bWJvbHtcdGhldGF9JCByZXByZXNlbnQgYWxsIG1vZGVsIHBhcmFtZXRlcnMuIFRoZSBpbXBsaWVkIGNvdmFyaWFuY2UgbWF0cml4IG9mIHRoZSBvYnNlcnZlZCB2YXJpYWJsZXMgJFxtYXRoYmZ7en0gPSAoXG1hdGhiZnt4fV5ULCBcbWF0aGJme3l9XlQsIFxtYXRoYmZ7d31eVCleVCQgaXM6DQoNCiQkDQpcYmVnaW57YWxpZ24qfQ0KXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KSA9IA0KXGJlZ2lue2JtYXRyaXh9DQpcYm9sZHN5bWJvbHtcU2lnbWF9X3t4eH0oXGJvbGRzeW1ib2x7XHRoZXRhfSkgJiBcYm9sZHN5bWJvbHtcU2lnbWF9X3t4eX0oXGJvbGRzeW1ib2x7XHRoZXRhfSkgJiBcYm9sZHN5bWJvbHtcU2lnbWF9X3t4d30oXGJvbGRzeW1ib2x7XHRoZXRhfSkgXFwNClxib2xkc3ltYm9se1xTaWdtYX1fe3l4fShcYm9sZHN5bWJvbHtcdGhldGF9KSAmIFxib2xkc3ltYm9se1xTaWdtYX1fe3l5fShcYm9sZHN5bWJvbHtcdGhldGF9KSAmIFxib2xkc3ltYm9se1xTaWdtYX1fe3l3fShcYm9sZHN5bWJvbHtcdGhldGF9KSBcXA0KXGJvbGRzeW1ib2x7XFNpZ21hfV97d3h9KFxib2xkc3ltYm9se1x0aGV0YX0pICYgXGJvbGRzeW1ib2x7XFNpZ21hfV97d3l9KFxib2xkc3ltYm9se1x0aGV0YX0pICYgXGJvbGRzeW1ib2x7XFNpZ21hfV97d3d9KFxib2xkc3ltYm9se1x0aGV0YX0pDQpcZW5ke2JtYXRyaXh9DQpcZW5ke2FsaWduKn0NCiQkDQoNCndoZXJlOg0KDQokJA0KXGJlZ2lue2FsaWduKn0NClxib2xkc3ltYm9se1xTaWdtYX1fe3h4fShcYm9sZHN5bWJvbHtcdGhldGF9KSAmPSBcYm9sZHN5bWJvbHtcTGFtYmRhfV94IFxib2xkc3ltYm9se1xQaGl9IFxib2xkc3ltYm9se1xMYW1iZGF9X3heVCArIFxib2xkc3ltYm9se1xUaGV0YX1fe1xkZWx0YX0gXFwNClxib2xkc3ltYm9se1xTaWdtYX1fe3l5fShcYm9sZHN5bWJvbHtcdGhldGF9KSAmPSBcYm9sZHN5bWJvbHtcTGFtYmRhfV95IChcbWF0aGJme0l9LVxtYXRoYmZ7Qn0pXnstMX0gKFxib2xkc3ltYm9se1xHYW1tYX0gXGJvbGRzeW1ib2x7XFBoaX0gXGJvbGRzeW1ib2x7XEdhbW1hfV5UICsgXGJvbGRzeW1ib2x7XEdhbW1hfV93IFxib2xkc3ltYm9se1xQaGl9X3cgXGJvbGRzeW1ib2x7XEdhbW1hfV93XlQgKyBcYm9sZHN5bWJvbHtcUHNpfSkgWyhcbWF0aGJme0l9LVxtYXRoYmZ7Qn0pXnstMX1dXlQgXGJvbGRzeW1ib2x7XExhbWJkYX1feV5UICsgXGJvbGRzeW1ib2x7XFRoZXRhfV97XGVwc2lsb259IFxcDQpcYm9sZHN5bWJvbHtcU2lnbWF9X3t3d30oXGJvbGRzeW1ib2x7XHRoZXRhfSkgJj0gXGJvbGRzeW1ib2x7XFBoaX1fdyBcXA0KXGJvbGRzeW1ib2x7XFNpZ21hfV97eHl9KFxib2xkc3ltYm9se1x0aGV0YX0pICY9IFxib2xkc3ltYm9se1xMYW1iZGF9X3ggXGJvbGRzeW1ib2x7XFBoaX0gXGJvbGRzeW1ib2x7XEdhbW1hfV5UIFsoXG1hdGhiZntJfS1cbWF0aGJme0J9KV57LTF9XV5UIFxib2xkc3ltYm9se1xMYW1iZGF9X3leVCBcXA0KXGJvbGRzeW1ib2x7XFNpZ21hfV97eHd9KFxib2xkc3ltYm9se1x0aGV0YX0pICY9IFxib2xkc3ltYm9se1xMYW1iZGF9X3ggXHRleHR7Q292fShcYm9sZHN5bWJvbHtceGl9LCBcbWF0aGJme3d9KSBcXA0KXGJvbGRzeW1ib2x7XFNpZ21hfV97eXd9KFxib2xkc3ltYm9se1x0aGV0YX0pICY9IFxib2xkc3ltYm9se1xMYW1iZGF9X3kgKFxtYXRoYmZ7SX0tXG1hdGhiZntCfSleey0xfSAoXGJvbGRzeW1ib2x7XEdhbW1hfSBcdGV4dHtDb3Z9KFxib2xkc3ltYm9se1x4aX0sIFxtYXRoYmZ7d30pICsgXGJvbGRzeW1ib2x7XEdhbW1hfV93IFxib2xkc3ltYm9se1xQaGl9X3cpDQpcZW5ke2FsaWduKn0NCiQkDQoNCioqNi4gTGlrZWxpaG9vZCBGdW5jdGlvbioqDQoNCkFzc3VtaW5nIG11bHRpdmFyaWF0ZSBub3JtYWxpdHkgb2YgdGhlIG9ic2VydmVkIHZhcmlhYmxlcyAkXG1hdGhiZnt6fSBcc2ltIE4oXGJvbGRzeW1ib2x7XG11fSwgXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KSkkLCB0aGUgbGlrZWxpaG9vZCBmdW5jdGlvbiBmb3IgYSBzYW1wbGUgb2YgJG4kIGluZGVwZW5kZW50IG9ic2VydmF0aW9ucyBpczoNCg0KJCQNClxiZWdpbnthbGlnbip9DQpMKFxib2xkc3ltYm9se1x0aGV0YX0pICY9IFxwcm9kX3tpPTF9Xm4gKDJccGkpXnstcC8yfSB8XGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KXxeey0xLzJ9IFxleHBcbGVmdFstXGZyYWN7MX17Mn0oXG1hdGhiZnt6fV9pIC0gXGJvbGRzeW1ib2x7XG11fSleVCBcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pXnstMX0gKFxtYXRoYmZ7en1faSAtIFxib2xkc3ltYm9se1xtdX0pXHJpZ2h0XQ0KXGVuZHthbGlnbip9DQokJA0KDQp3aGVyZSAkcCA9IDcgKyA5ICsgNSA9IDIxJCBpcyB0aGUgdG90YWwgbnVtYmVyIG9mIG9ic2VydmVkIHZhcmlhYmxlcy4NCg0KVGhlIGxvZy1saWtlbGlob29kIGZ1bmN0aW9uIGlzOg0KDQokJA0KXGJlZ2lue2FsaWduKn0NClxlbGwoXGJvbGRzeW1ib2x7XHRoZXRhfSkgJj0gLVxmcmFje25wfXsyfSBcbG9nKDJccGkpIC0gXGZyYWN7bn17Mn0gXGxvZ3xcYm9sZHN5bWJvbHtcU2lnbWF9KFxib2xkc3ltYm9se1x0aGV0YX0pfCBcXA0KJlxxdWFkIC0gXGZyYWN7MX17Mn0gXHN1bV97aT0xfV5uIChcbWF0aGJme3p9X2kgLSBcYm9sZHN5bWJvbHtcbXV9KV5UIFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSleey0xfSAoXG1hdGhiZnt6fV9pIC0gXGJvbGRzeW1ib2x7XG11fSkNClxlbmR7YWxpZ24qfQ0KJCQNCg0KRm9yIGVzdGltYXRpb24sIHdlIHR5cGljYWxseSB1c2UgdGhlIGRpc2NyZXBhbmN5IGZ1bmN0aW9uOg0KDQokJA0KXGJlZ2lue2FsaWduKn0NCkZfe01MfShcYm9sZHN5bWJvbHtcdGhldGF9KSAmPSBcbG9nfFxib2xkc3ltYm9se1xTaWdtYX0oXGJvbGRzeW1ib2x7XHRoZXRhfSl8ICsgXHRleHR7dHJ9KFxtYXRoYmZ7U30gXGJvbGRzeW1ib2x7XFNpZ21hfShcYm9sZHN5bWJvbHtcdGhldGF9KV57LTF9KSAtIFxsb2d8XG1hdGhiZntTfXwgLSBwDQpcZW5ke2FsaWduKn0NCiQkDQoNCndoZXJlICRcbWF0aGJme1N9JCBpcyB0aGUgc2FtcGxlIGNvdmFyaWFuY2UgbWF0cml4Lg0KDQoqKjcuIFBhcmFtZXRlcnMgdG8gRXN0aW1hdGUqKg0KDQpUaGUgbW9kZWwgcGFyYW1ldGVycyBpbmNsdWRlOg0KDQoNCiogRmFjdG9yIGxvYWRpbmdzOiAkXGxhbWJkYV97aWp9JCBpbiAkXGJvbGRzeW1ib2x7XExhbWJkYX1feCQgYW5kICRcYm9sZHN5bWJvbHtcTGFtYmRhfV95JA0KKiBTdHJ1Y3R1cmFsIGNvZWZmaWNpZW50czogJFxiZXRhX3tpan0kIGluICRcbWF0aGJme0J9JCwgJFxnYW1tYV97aWp9JCBpbiAkXGJvbGRzeW1ib2x7XEdhbW1hfSQsICRcZ2FtbWFfe2lqfV53JCBpbiAkXGJvbGRzeW1ib2x7XEdhbW1hfV93JA0KKiBWYXJpYW5jZXMgYW5kIGNvdmFyaWFuY2VzOiAkXHBoaV97aWp9JCBpbiAkXGJvbGRzeW1ib2x7XFBoaX0kLCAkXHBzaV97aWp9JCBpbiAkXGJvbGRzeW1ib2x7XFBzaX0kLCAkXHBoaV97dyxpan0kIGluICRcYm9sZHN5bWJvbHtcUGhpfV93JA0KKiAgTWVhc3VyZW1lbnQgZXJyb3IgdmFyaWFuY2VzOiAkXHRoZXRhX3tcZGVsdGEsaX0kIGluICRcYm9sZHN5bWJvbHtcVGhldGF9X3tcZGVsdGF9JCwgJFx0aGV0YV97XGVwc2lsb24saX0kIGluICRcYm9sZHN5bWJvbHtcVGhldGF9X3tcZXBzaWxvbn0kDQoNCg0KDQpUeXBpY2FsbHksIHdlIHNldCBvbmUgbG9hZGluZyBwZXIgbGF0ZW50IHZhcmlhYmxlIHRvIDEgZm9yIGlkZW50aWZpY2F0aW9uLg0KDQoqKjguIE1vZGVsIElkZW50aWZpY2F0aW9uKioNCg0KVGhlIG1vZGVsIGlzIGlkZW50aWZpZWQgaWY6DQoNCiogIEVhY2ggbGF0ZW50IHZhcmlhYmxlIGhhcyBhdCBsZWFzdCAzIGluZGljYXRvcnMgKHNhdGlzZmllZCkNCiogIFRoZSBzY2FsZSBvZiBlYWNoIGxhdGVudCB2YXJpYWJsZSBpcyBzZXQgYnkgZml4aW5nIG9uZSBsb2FkaW5nIHRvIDENCiogIFRoZSBtb2RlbCBtZWV0cyB0aGUgb3JkZXIgY29uZGl0aW9uIGFuZCByYW5rIGNvbmRpdGlvbiBmb3IgaWRlbnRpZmljYXRpb24NCg0KDQoNCg0KDQo=